Antlr4 C# targets and output path of generated fil

2019-03-13 06:32发布

问题:

I have a C# solution with an Antlr3 grammar file, and I'm trying to upgrade to Anltr4. It turns out the grammar was the easy part (it became better, and one third the size!). Generating the parser turned out to be the tricky part.

In the old solution I merely ran AntlrWorks to update the lexer and parser .cs files when the grammar file changed. The lexer and parser were included directly in the same project as the grammar so the framework around the parser could make use of them directly.

With the Antlr4 targets for C# I noticed that (at least by default) the output path of the generated Parser C# classes is in the intermediate directory, e.g. obj\Debug. This means I can't use the parser directly in the same project. Am I supposed to change the output path if I want the generated source usable in my sln? Don't I want it in my sln?

I tried making a separate project for the parser generation, that is, a project containing only the grammar file. When this project is built using the Antlr4 targets, the resulting assembly can be referenced from projects needing the parser classes. However, if this project is included in the solution I still don't get any intellisense in visual studio since it bases its intellisense on source files for loaded projects, so it is still not quite usable. The only way I could get it working properly was to build then unload the parser project, and have other projects reference it as an assembly file rather than a project.

EDIT:

After looking on the antlr-interest list I found this thread indicating that the problem with intellisense may be Resharpers fault. If this is the case, then my question is rather how to keep using both Antlr4 and Resharper in my solution? https://groups.google.com/forum/#!topic/antlr-discussion/QSuJXphaBDg

回答1:

You are encountering a known bug with ReSharper. The ANTLR 3 and ANTLR 4 C# build integration is reliable, and uses long-established patterns that Microsoft uses with other languages and code generation tasks. Your options are:

  1. Stop using ReSharper
  2. Get the ReSharper authors to address the lack of support for this feature, or
  3. Modify the ANTLR 4 target to work around the limitation in ReSharper, which will introduce other problems into the build which may or may not be acceptable for your use.

Option 1 is certainly the least expensive, and most likely to provide reliable long-term support for your projects.



回答2:

I found an extension for Resharper: ReSharper.ExternalCode.

Tip for Antlr: add obj\Debug in Resharper -> Code Inspection -> External Code and reload solution.

It's works for me.



回答3:

There is an easy way to get the best of both Antlr 4 and Visual Studio. You are on the right track in having a separate grammar project and implementation project, but you are missing a couple steps.

Follow these steps to get the Intellisense working

  • In Visual Studio, go to Tools -> Extensions and Updates and search the Online section for "ANTLR Language Support" by Sam Harwell.
    • This does a few things:
      • Adds Templates for the combined grammars.
      • Adds Syntax Highlighting
      • Adds an MSBuild target for the grammar to generate the parser.
  • In your solution, set up your project structure like this:
    • Solution
      • Grammar Project
        • ANTLR 4 Combined Grammar
      • Implementation Project
        • Folder for Links to Generated files
        • Listener Implementation Class
  • Write and Compile your grammar.
  • In your folder for the Links to Generated Files, Right-Click the folder and click Add -> Existing Item
  • Browse to Grammar Project\obj\Debug and select all the generated parser files.
  • This next step is important. On the Add button there is a little drop-down arrow. Click the drop-down arrow and click "Add As Link".
    • This will add the generated files to the implementation project using a symbolic link instead of a direct copy.
    • This gives the added benefit of not having to remove and re-add the parser files if you have to change your grammar later.
  • Intellisense should work now for your generated parser classes, and you don't even have to disable ReSharper.