问题描述
我已按照 these 说明进行操作,但在编译文件后出现大量编译错误。
我做了什么:
- 在 .NET Core 3.1 中创建了一个新的控制台项目。
- 已安装 NuGet 包 Antlr4。
- 在项目中添加了一个名为
example.g4
的新文本文件,并将其保存为无签名的 UTF-8 编码。 - 使用一些演示功能填充语法。
- 构建解决方案。
- 成功编译词法分析器/访问者/解析器等后出现大量错误。
The name '_interp' does not exist in the current context AntlrDemo C:\AntlrDemo\obj\Debug\netcoreapp3.1\exampleLexer.cs 45 Active
'ParserATNSimulator' does not contain a constructor that takes 2 arguments AntlrDemo C:\AntlrDemo\obj\Debug\netcoreapp3.1\exampleParser.cs 95 Active
'exampleParser.TokenNames': no suitable method found to override AntlrDemo C:\AntlrDemo\obj\Debug\netcoreapp3.1\exampleParser.cs 69 Active
怎么回事?
问题不在于语法 - 它在 .NET Framework 中成功编译。
解决方法
安装 Antlr4
NuGet 包后,以下代码会添加到您的 .csproj 文件中:
<ItemGroup>
<PackageReference Include="Antlr4" Version="4.6.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
解决方法是将上述内容更改为以下内容:
<ItemGroup>
<PackageReference Include="Antlr4" Version="4.6.6">
<!--<PrivateAssets>all</PrivateAssets>-->
</PackageReference>
</ItemGroup>
它似乎也可以通过取消注释 PrivateAssets
元素来工作。但我不知道这里的实际问题是什么,如果我做错了什么。有人可以解释一下吗?
编辑:另一种替代解决方案是安装两个 NuGet 包 Antlr4.CodeGenerator
和 Antlr4.Runtime
。
如果您不介意使用官方的 Antlr4 代码生成器和运行时,但又不想实际手动下载和安装 Java 和 Antlr Tool .jar,请尝试以下操作:
- 安装最新的 NET 5,或使用旧的 NET Core。
- dotnet new -i Antlr4BuildTasks.Templates
- mkdir Foo
- cd Foo
- dotnet 新 antlr
- dotnet 构建
- dotnet 运行
这确实使用了 Antlr4 Java 工具,但它是完全隐藏的。您无需下载运行时,也无需下载 Java。它全部包含在您刚刚在 .csproj 中引用的 Antlr4BuildTasks 工具中。如果您想使用较旧的 Antlr4 版本,例如 4.8 或 4.7,Antlr4BuildTasks 将从 Maven Central 和 NuGet.org 下载工具和运行时;您只需在 .csproj 文件中设置版本,然后“dotnet build”即可。
我有另一个工具可以为 C#(官方和 Harwell 版本)、Java 和 JavaScript 目标生成语法驱动程序和支持代码。它现在用于 github.com/antlr/grammars-v4 中的 CI。
如果您尝试在 Antlr4(官方 Antlr4)和 Antlr4cs(Harwell 的工具/运行时)之间交换,您会发现工具和运行时完全不同。没有 shim 允许为一个运行时编写的代码用于另一个运行时,但我正在研究一个。
就 .csproj 文件中的 <PrivateAssets>
代码而言,按照您的建议去掉这些行是可以的。包含它的原因是不要将构建工具的依赖程序集直接传播到您的代码中。但是,虽然该工具仅用于构建应用而非运行应用,但 <PrivateAssets>
不会阻止工具本身的程序集仍被包含在内。
--肯