在 .NET 应用中使用 ANTLR
什么是 ANTLR ?
ANTLR 是功能強(qiáng)大的解析器生成器,用于讀取,處理,執(zhí)行或翻譯結(jié)構(gòu)化文本或二進(jìn)制文件。它被廣泛用于構(gòu)建語言,工具和框架。ANTLR從語法中生成一個(gè)解析器,該解析器可以構(gòu)建和遍歷解析樹。
ANTLR 語法庫
ANTLR 為常見的語言構(gòu)建了語法文件, 可以直接下載使用 https://github.com/antlr/grammars-v4 。如果需要在程序中處理常用的語言, 可以先來這里找一下。
如何在 .NET 中使用 ANTLR ?
ANTLR 被廣泛應(yīng)用與大數(shù)據(jù)分析、 人工智能等領(lǐng)域的語法分析, 網(wǎng)上的相關(guān)資料確實(shí)非常多, 但是 .NET 相關(guān)的資料卻很少, 有的也是年代久遠(yuǎn), 幾乎沒有什么參考價(jià)值。
經(jīng)過一番摸索, 終于找到了在 .NET 中使用 ANTLR 的正確方法, 于是記錄下來。
新建 .NET 命令行項(xiàng)目
首先, 當(dāng)然是新建一個(gè) .NET 項(xiàng)目, 命令如下:
dotnet new console AntlrDemo添加 NuGet 包 Antlr4.Runtime.Standard , 目前的版本是 4.9.2 , 這是一個(gè) .NET Standard 2.0 標(biāo)準(zhǔn)類庫, 可以在大多數(shù) .NET 環(huán)境中使用:
dotnet add package Antlr4.Runtime.Standard --version 4.9.2生成 C# 代碼
下載 ANTLR 工具包
訪問 ANTLR 的?下載?頁面, 下載完整的 ANTLR jar 包, 需要用這個(gè)來生成 C# 源代碼。
由于要運(yùn)行 jar 文件, 所以還得裝一個(gè) jre , 不過運(yùn)行時(shí)不需要 jre 。
根據(jù)語法文件生成對應(yīng)的 C# 代碼
以 ANTLR 提供的 SQLite 語法文件為例, 生成代碼的命令為:
java -jar .tools/antlr-4.9.2-complete.jar \-Dlanguage=CSharp \ # 指定生成的語言為 C#-package AntlrDemo.Generated \ # 指定輸出代碼的命名空間-o ./src/AntlrDemo/Generated \ # 指定輸出的目錄SQLiteParser.g4 SQLiteLexer.g4 # 提供語法文件編譯一下, 確認(rèn)沒有錯(cuò)誤
dotnet build使用生成的 C# 代碼
要使用生成的 C# 代碼, 根據(jù) ANTLR 針對的 C# 說明?, 對應(yīng)的代碼如下:
var sql = "select * from t where id < 10"; ICharStream charStream = CharStreams.fromString(sql); ITokenSource lexer = new SQLiteLexer(charStream); ITokenStream stream = new CommonTokenStream(lexer); SQLiteParser parser = new SQLiteParser(stream); parser.BuildParseTree = true; IParseTree tree = parser.parse();上面的代碼創(chuàng)建了解釋器 (parser) 和 對應(yīng)的語法樹 (tree) 兩個(gè)對象, 有了它們之后, 可以做類似下面的操作:
判斷是否存在語法錯(cuò)誤
如果要簡單判斷 sql 的內(nèi)容有沒有語法錯(cuò)誤的話, 可以讀取?parser?的?NumberOfSyntaxErrors?屬性進(jìn)行判斷
if (parser.NumberOfSyntaxErrors > 0) {throw new Exception("Invalid SQL!"); }檢查語法樹的每一個(gè)節(jié)點(diǎn)
比如 where 后面的每一個(gè)表達(dá)式是否合法, 不能出現(xiàn)?1=1?之類的表達(dá)式, 則需要使用?ParseTreeWalker?來循環(huán)整個(gè)語法樹。
先創(chuàng)建一個(gè)自定義的監(jiān)聽器, 代碼如下:
public class SqliteParserListener : SQLiteParserBaseListener {// 只監(jiān)聽退出表達(dá)式的方法, 根據(jù)提供的語法文件, 還會有很多其它的方法可以重寫。public override void ExitExpr([NotNull] SQLiteParser.ExprContext context) {var text = context.GetText();Console.WriteLine(text);} }調(diào)用監(jiān)聽器?SqliteParserListener?并循環(huán)整個(gè)語法樹的代碼為:
var listener = new SqliteParserListener(); ParseTreeWalker.Default.Walk(listener, tree);
ANTLR 使用小結(jié)
ANTLR 是一個(gè)通用的解析器生成器, 只要能夠構(gòu)建語法文件, 就能生成對應(yīng)的解析器, 生成對應(yīng)的語法樹進(jìn)行分析。不僅提供了大量的語法文件, 也可以根據(jù)語法創(chuàng)建自定義的語法文件, 各家的 IDE 工具 (JetBrains, Visual Studio, Visual Studio Code, Eclipse 等)也都對其語法文件提供了可視化支持, 如果需要在代碼中動(dòng)態(tài)分析解釋特定的語法, ANTLR 可以說是首選工具。
總結(jié)
以上是生活随笔為你收集整理的在 .NET 应用中使用 ANTLR的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面向.NET开发人员的Dapr- act
- 下一篇: 我用段子讲.NET之依赖注入(一)