2016-12-30 58 views
2

我想在Mono上使用C#中的ANTLR 4.5.3解析器(從macintosh 10.11.3上的Xamarin Studio 6.1.2運行),但生成的代碼由antlr4 Java命令行工具有一個錯誤,它會阻止編譯。C#ANTLR解析器沒有實現繼承的抽象成員TokenNames.get

我的語法如下:

grammar Hello; 

HELLO: 'hello'; 
WORD: [a-z]+; 

greeting: HELLO WORD; 

WS: [ \n\t\r]+ -> skip; 

當語法通過antlr4通過沒有任何錯誤或警告,但所產生的HelloParser類Xamarin工作室編譯失敗:

錯誤CS0534:HelloParser未實現繼承的抽象成員Antlr4.Runtime.Recognizer<Antlr4.Runtime.IToken,Antlr4.Runtime.Atn.ParserATNSimulator>.TokenNames.get(CS0534)

我有相應的ANTLR 4.5.3 NuGet包,並且沒有其他錯誤。結果解析器類的其餘部分看起來沒問題。 (生成GreetingContext類和HelloParser.greeting方法。)

爲什麼ANTLR不生成此方法,以及如何解決此錯誤?

如果需要的話,這裏是HelloParser.cs文件的全部:

//------------------------------------------------------------------------------ 
// <auto-generated> 
//  This code was generated by a tool. 
//  ANTLR Version: 4.5.3 
// 
//  Changes to this file may cause incorrect behavior and will be lost if 
//  the code is regenerated. 
// </auto-generated> 
//------------------------------------------------------------------------------ 

// Generated from Hello.g4 by ANTLR 4.5.3 

// Unreachable code detected 
#pragma warning disable 0162 
// The variable '...' is assigned but its value is never used 
#pragma warning disable 0219 
// Missing XML comment for publicly visible type or member '...' 
#pragma warning disable 1591 
// Ambiguous reference in cref attribute 
#pragma warning disable 419 

using System; 
using System.Text; 
using System.Diagnostics; 
using System.Collections.Generic; 
using Antlr4.Runtime; 
using Antlr4.Runtime.Atn; 
using Antlr4.Runtime.Misc; 
using Antlr4.Runtime.Tree; 
using DFA = Antlr4.Runtime.Dfa.DFA; 

[System.CodeDom.Compiler.GeneratedCode("ANTLR", "4.5.3")] 
[System.CLSCompliant(false)] 
public partial class HelloParser : Parser { 
    public const int 
     HELLO=1, WORD=2, WS=3; 
    public const int 
     RULE_greeting = 0; 
    public static readonly string[] ruleNames = { 
     "greeting" 
    }; 

    private static readonly string[] _LiteralNames = { 
     null, "'hello'" 
    }; 
    private static readonly string[] _SymbolicNames = { 
     null, "HELLO", "WORD", "WS" 
    }; 
    public static readonly IVocabulary DefaultVocabulary = new Vocabulary(_LiteralNames, _SymbolicNames); 

    [NotNull] 
    public override IVocabulary Vocabulary 
    { 
     get 
     { 
      return DefaultVocabulary; 
     } 
    } 

    public override string GrammarFileName { get { return "Hello.g4"; } } 

    public override string[] RuleNames { get { return ruleNames; } } 

    public override string SerializedAtn { get { return _serializedATN; } } 

    public HelloParser(ITokenStream input) 
     : base(input) 
    { 
     Interpreter = new ParserATNSimulator(this,_ATN); 
    } 
    public partial class GreetingContext : ParserRuleContext { 
     public ITerminalNode HELLO() { return GetToken(HelloParser.HELLO, 0); } 
     public ITerminalNode WORD() { return GetToken(HelloParser.WORD, 0); } 
     public GreetingContext(ParserRuleContext parent, int invokingState) 
      : base(parent, invokingState) 
     { 
     } 
     public override int RuleIndex { get { return RULE_greeting; } } 
     public override void EnterRule(IParseTreeListener listener) { 
      IHelloListener typedListener = listener as IHelloListener; 
      if (typedListener != null) typedListener.EnterGreeting(this); 
     } 
     public override void ExitRule(IParseTreeListener listener) { 
      IHelloListener typedListener = listener as IHelloListener; 
      if (typedListener != null) typedListener.ExitGreeting(this); 
     } 
    } 

    [RuleVersion(0)] 
    public GreetingContext greeting() { 
     GreetingContext _localctx = new GreetingContext(Context, State); 
     EnterRule(_localctx, 0, RULE_greeting); 
     try { 
      EnterOuterAlt(_localctx, 1); 
      { 
      State = 2; Match(HELLO); 
      State = 3; Match(WORD); 
      } 
     } 
     catch (RecognitionException re) { 
      _localctx.exception = re; 
      ErrorHandler.ReportError(this, re); 
      ErrorHandler.Recover(this, re); 
     } 
     finally { 
      ExitRule(); 
     } 
     return _localctx; 
    } 

    private static string _serializedATN = _serializeATN(); 
    private static string _serializeATN() 
    { 
     StringBuilder sb = new StringBuilder(); 
     sb.Append("\x3\x430\xD6D1\x8206\xAD2D\x4417\xAEF1\x8D80\xAADD\x3\x5"); 
     sb.Append("\b\x4\x2\t\x2\x3\x2\x3\x2\x3\x2\x3\x2\x2\x2\x3\x2\x2\x2\x6\x2"); 
     sb.Append("\x4\x3\x2\x2\x2\x4\x5\a\x3\x2\x2\x5\x6\a\x4\x2\x2\x6\x3\x3\x2"); 
     sb.Append("\x2\x2\x2"); 
     return sb.ToString(); 
    } 

    public static readonly ATN _ATN = 
     new ATNDeserializer().Deserialize(_serializedATN.ToCharArray()); 
} 

評論,如果您需要任何其他生成的文件的情況下,錯誤是不可再生用自己的ANTLR。

+1

您可能在工具和運行時庫之間存在版本不匹配。仔細檢查一下。另外,如果您使用NuGet的運行時,IIRC您需要使用Sam Harwell的工具版本,除非更改。爲了確保,抓住NuGet,解壓縮並使用裏面的工具。 –

+1

太棒了!我進入了NuGet包的* tools目錄,並將ANTLR jar替換爲那裏的那個,現在它工作正常(儘管我必須將命令改爲'antlr4 Hello.g4 -Dlanguage = CSharp_v4_5',而不是'antlr4 Hello.g4 -Dlanguage = CSharp')。作爲回答發佈,我會接受。 –

回答

2

NuGet包使用​​而不是標準包。您不能使用一個版本的工具和另一個版本的運行時庫,它們不兼容:查看release notes here

所以,如果你想繼續使用NuGet軟件包,你可以使用裏面的工具 - 軟件包只是一個zip文件。

我不知道您是否可以使用Xamarin Studio簡化這個工作流程,但是使用Visual Studio,您可以完全跳過手動解析器生成步驟,因爲該包與MSBuild集成以在編譯時生成解析器代碼。

+0

@Sam感謝您的糾正。你碰巧有任何機會描述你的優化是什麼?我有興趣瞭解更多。 –

+1

https://github.com/tunnelvisionlabs/antlr4/blob/master/doc/optimized-fork.md –

+0

@Sam謝謝!我在antlr4cs回購庫中尋找它,這就是爲什麼我找不到它。 –