--- tags: 開發環境, ANTLR 4, C# --- # ANTLR 4開發環境設置 ANTLR (**AN**other **T**ool for **L**anguage **R**ecognition)是用來做語法解析的工具,可產生的解析器語言支援Java、C#、Python、JavaScript、Go、C++、Swift、PHP,本篇介紹的是C#的部分。 ## Java安裝 ANTLR是用Java開發的,所以必須先安裝Java,我使用的是[AdoptOpenJDK][link-1],OpenJDK 8 (LTS) - HotSpot的版本。 1. 將下載的檔案解壓縮到C槽。 2. 在環境變數`path`加入`C:\jdk8u242-b08\bin`。 完成以上步驟可在終端機輸入`java -version`確認是否設置成功。 ![Java check][img-1] [link-1]: https://adoptopenjdk.net/ ## ANTLR 4安裝 1. 到[ANTLR官網][link-2]下載`antlr-4.8-complete.jar`並儲存到`C:\jdk8u242-b08\lib`。 2. 在環境變數`CLASSPATH`加入 `.;C:\jdk8u242-b08\lib\antlr-4.8-complete.jar;%CLASSPATH%`。 3. 在`C:\jdk8u242-b08\bin`建立一個`antlr4.bat`檔案,內容為 `java org.antlr.v4.Tool %*`。 4. 在`C:\jdk8u242-b08\bin`建立一個`grun.bat`檔案,內容為 `java org.antlr.v4.gui.TestRig %*`。 完成以上步驟可在終端機輸入`antlr4`確認是否設置成功。 ![ANTLR4 check][img-2] [link-2]: https://www.antlr.org/download.html ## Visual Studio Code設置 ### 環境設置 1. 安裝ANTLR4 grammar syntax support擴充套件。 ![ANTLR4 grammar syntax support][img-3] 2. 在`settings.json`加入以下設定。 ```json "antlr4.generation": { "mode": "external", "outputDir": "antlr4-runtime", //產生的解析器檔案存放的資料夾 "language": "CSharp", //產生的解析器語言 "listeners": false, "visitors": true } ``` ### ANTLR專案設置 1. 在`launch.json`的`configurations`加入以下設定。 ```json { "name": "Debug ANTLR4", "type": "antlr-debug", "request": "launch", "input": "input.txt", //要解析的檔案 "startRule": "expr", //起始規則 "printParseTree": true, //編譯後顯示文字樹狀圖 "visualParseTree": false //編譯後顯示圖形樹狀圖 } ``` 2. 建立ANTLR的解析規則檔,副檔名為`.g4`,並在第一行加入`grammar 檔名;`。 例如:檔名為`Hello.g4`,則此檔案第一行為`grammar Hello;`。 ANTLR基本語法:`規則名稱 : 規則內容1 | 規則內容2 ;` 規則名稱第一個字母小寫為parser,大寫為lexer。 ## Visual Studio C#專案設置 1. 從NuGet安裝Antlr4.Runtime.Standard套件。 ![Antlr4.Runtime.Standard][img-4] 2. 將ANTLR產生的四支`.cs`檔複製到C#專案裡。 3. 加入using命名空間指示詞。 ```csharp using Antlr4.Runtime; using Antlr4.Runtime.Tree; ``` 加入以下程式碼可開始解析。 ```csharp ICharStream stream = CharStreams.fromPath(openFileDialog1.FileName); ITokenSource lexer = new HelloLexer(stream); ITokenStream tokens = new CommonTokenStream(lexer); HelloParser parser = new HelloParser(tokens); IParseTree tree = parser.expr(); HelloVisitor visitor = new HelloVisitor(); visitor.Visit(tree); ``` 如果要在某些解析規則中做一些處理,需先加入以下class,然後才在這個class裡加入要處理的function。 ```csharp public class HelloVisitor : HelloBaseVisitor<object> { function1() {...} function2() {...} } ``` 要處理的function是從`HelloVisitor.cs`找出和ANTLR規則名稱相對應的function後修改而成。 例如:`Result VisitExpr([NotNull] HelloParser.ExprContext context);` function長相: ```csharp public override object VisitExpr(HelloParser.ExprContext context) { do things... return VisitChildren(context); } ``` --- **參考資料** [ANTLR官網](https://www.antlr.org/) [作者GitHub](https://github.com/antlr/antlr4/tree/master/doc) [The ANTLR Mega Tutorial](https://tomassetti.me/antlr-mega-tutorial/) [img-1]: https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoQhugoCZZEsJoM-ywUhfd_C_HL9hkgwbL4-s_X6ltqJduyg2gsiYBoTr4DnQJXmmY8ziCI-nf_D2qijK11sQSXDmCJT4shR4QiXok8CvMxdU62PuB35fJu4qW2xCBgmY0FOEmfEiV6IdogIWiiYa_gwbB56VJidPOPwywBZm3M6NI-iH0uEJ38uBDZEjv/s1600/01_java-check.png [img-2]: https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghx7WNoMIQK7H06hGFYg-3juXpPILZJiuo9R7a8678SMpxZibjiGw4ICew4Qil_H6sKwGXfBKclvNpMHTwU8SH1bZBgeZRUVjJ_rwjPx05R0AHijHQPAJXhvRrXs76Eu0LvYrq-YCZd8EEgMcGSHHmEIhBvw4p6Tus5IvS8qOzAQ7dDa4Ze7f6WZYWGbpE/s1600/02_antlr4-check.png [img-3]: https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZcwJzCRJT3qHvYftMRAnu29Ne0dzhTBMZqpCjFqKelpObNPmkXD2GciXx87U4XOktnVV-MphgkTrqyNoS7wTCmVAo13qBW7pwJ0f-CaMZFG9qdgIwldLhuqazFSPugBGgT3Jl5_rqMeyHVIXNyUmWlZsjDk1J28p0sJokCxHqsq7Rb38ZvCmMaDia4LdL/s1600/03_antlr4-grammar-syntax-support.png [img-4]: https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_WAN4T8xIehmaUuIiMfMThswUrgkwt_K8PF0m7P42h1vAEi06WWdWEQ423qE5bzdZ2j6ZY2k2TaKMMR3vYGQ_q6UGCis-ydRtoOarlBiFaySNJiNfzgP1xE4zK2KjuFJW92zzpXr67GtYMa0u9kHJJ1mxMwgvxLNb1NIqf-s_Ozxs2p-5Ru_6px7KBYpX/s1600/04_antlr4-runtime-standard.png