我想使用 Antlr4 来解析我的 C# 应用程序中的一些文件。到目前为止,鉴于我的语法,我已经能够生成解析器和词法分析器文件。现在我想在文件中使用读取并将解析器和词法分析器应用于它们。我一直在寻找有关如何做到这一点的文档,但我做得不够。我发现了一些使用以前版本的 Antlr 的旧示例,但它们似乎不适用于 Antlr4。任何帮助,将不胜感激。谢谢。
4 回答
- 在 Visual Studio 中,转到工具 -> 扩展和更新并在在线部分搜索 Sam Harwell 的“ANTLR 语言支持”。更多信息可以在GitHub 项目网站上找到
- 这做了几件事:
- 为组合语法添加模板。
- 添加语法高亮
- 为语法添加 MSBuild 目标以生成解析器。
- 这做了几件事:
- 在您的解决方案中,设置您的项目结构,如下所示:
- 解决方案
- 语法项目
- 计算器.g4
- 实施项目
- GeneratedFiles(此文件夹中的所有文件都作为链接添加到位于 GrammarProject\obj\Debug 中的文件)
- CalculatorBaseListener.cs
- CalculatorBaseVisitor.cs
- 计算器Lexer.cs
- CalculatorListener.cs
- 计算器解析器.cs
- CalculatorVistor.cs
- MyCalcualtorImplementation.cs
- GeneratedFiles(此文件夹中的所有文件都作为链接添加到位于 GrammarProject\obj\Debug 中的文件)
- 语法项目
- 解决方案
- 编写和编译你的语法。
- 在指向生成文件的链接的文件夹中,右键单击该文件夹,然后单击添加 -> 现有项目
- 浏览到 Grammar Project\obj\Debug 并选择所有生成的解析器文件。
- 下一步很重要。在添加按钮上有一个小的下拉箭头。单击下拉箭头,然后单击“添加为链接”。
- 这将使用符号链接而不是直接复制将生成的文件添加到实现项目中。
- 如果您以后必须更改语法,这会带来额外的好处,即不必删除和重新添加解析器文件。
- 一旦你做到了这一点,那么你可以从 GrammarProject.CalculatorBaseListener 或 GrammarProject.CalculatorBaseParser 继承,这取决于你决定使用什么开发模式。
作为旁注, Terence Parr 的“The Definitive ANTLR 4 Reference”是了解 ANTLR4 工作原理和不同开发模式的绝佳资源。所有示例都使用 Java,但这些概念适用于 Java 和 C#。
尝试
using (StreamReader fileStream = new StreamReader(fileName)) {
AntlrInputStream inputStream = new AntlrInputStream(fileStream);
SearchLexer lexer = new SearchLexer(inputStream);
CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);
SearchParser parser = new SearchParser(commonTokenStream);
parser.RemoveErrorListeners();
parser.AddErrorListener(new ErrorListener()); // add ours
parser.root();
}
我正在使用 Visual Studio 2019 Professional(最新版本 16.7.3)
至于现在ANTLR 语言支持不适用于 VS 2019。有一个非官方版本可用https://github.com/tunnelvisionlabs/antlr4cs/issues/353但它不抱怨 VS2019 扩展 API(更多信息在这里:https:// /devblogs.microsoft.com/visualstudio/updates-to-synchronous-autoload-of-extensions-in-visual-studio-2019/)
您可以尝试以下(.net 标准库的步骤)
安装 VS 扩展 AntlrVSIX 8.0(使用扩展管理器)
创建一个 .NET 标准库项目 (MyLib.Parser.Grammar)
创建了一个虚拟(.cs)类 - 不确定它是否仍然需要,如果项目只包含语法文件,过去会出现一些问题
参考以下包(使用 Nuget)
- Antlr4.Runtime.Standard
- Antlr4BuildTasks
添加语法文件 (.g4) 例如,您可以使用此处提供的语法存储库 https://github.com/antlr/grammars-v4
假设您想解析 TSQL ( https://github.com/antlr/grammars-v4/tree/master/sql/tsql ) - 将 TSqlParser.g4 和 TSqllexer.g4 添加到您的项目中
编辑项目文件 MyLib.Parser.Grammar.csproj,它应该看起来像
<PropertyGroup> <TargetFramework>netstandard2.1</TargetFramework> </PropertyGroup> <ItemGroup> <Antlr4 Include="TSqlLexer.g4"> <Package>MyLib.Parser</Package> <Visitor>true</Visitor> <Error>false</Error> <Listener>true</Listener> </Antlr4> <Antlr4 Include="TSqlParser.g4"> <Package>MyLib.Parser</Package> <Visitor>true</Visitor> <Error>false</Error> <Listener>true</Listener> </Antlr4> </ItemGroup> <ItemGroup> <PackageReference Include="Antlr4.Runtime.Standard" Version="4.8.0" /> <PackageReference Include="Antlr4BuildTasks" Version="8.3.0" /> </ItemGroup> </Project>
此时,当您构建 MyLib.Parser.Grammar 项目时,Antlr4BuildTasks 工具将创建解析器 .cs 文件,但它们将在项目
bin
文件夹中可用(例如\MyLib.Parser.Grammar\bin\Debug\netstandard2.1
)创建另一个库项目 MyLib.Parser
创建项目依赖项,以便在 MyLib.Parser 之前构建 MyLib.Parser.Grammar
使用项目定义中的 AntOutDir 属性和相对路径将输出文件从 MyLib.Parser.Grammar 定向到 MyLib.Parser 项目。现在项目文件中的 Antlr4 部分应该类似于:
<ItemGroup> <Antlr4 Include="TSqlLexer.g4"> <Package>MyLib.Parser</Package> <Visitor>true</Visitor> <Error>false</Error> <Listener>true</Listener> <AntOutDir>..\MyLib.Parser</AntOutDir> </Antlr4> <Antlr4 Include="TSqlParser.g4"> <Package>MyLib.Parser</Package> <Visitor>true</Visitor> <Error>false</Error> <Listener>true</Listener> <AntOutDir>..\MyLib.Parser</AntOutDir> </Antlr4> </ItemGroup>
- 现在重建后,生成的 .cs 文件应该会自动添加到 MyLib.Parser 项目中
这是 ErrorListener 的示例
public class ErrorListener : BaseErrorListener
{
public void SyntaxError(IRecognizer recognizer, int offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
{
Console.WriteLine("{0}: line {1}/column {2} {3}", e, line, charPositionInLine, msg);
}
}