2016-12-30 2 views
2

Я пытаюсь использовать ANTLR 4.5.3-парсер в C# в Mono (работает от Xamarin Studio 6.1.2 на macOS 10.11.3), но код сгенерирован с помощью инструмента командной строки antlr4 имеет одну ошибку, которая предотвращает компиляцию.C# ANTLR parser не реализует унаследованный абстрактный член TokenNames.get

Моя грамматика выглядит следующим образом:

grammar Hello; 

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

greeting: HELLO WORD; 

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

Когда грамматика проходит через antlr4 нет никаких ошибок или предупреждений, но в Xamarin студии компиляции полученного HelloParser класса терпит неудачу с:

Ошибка CS0534: HelloParser не реализует унаследованный абстрактный элемент Antlr4.Runtime.Recognizer<Antlr4.Runtime.IToken,Antlr4.Runtime.Atn.ParserATNSimulator>.TokenNames.get (CS0534)

У меня есть соответствующий пакет ANTLR 4.5.3 NuGet, и никаких других ошибок нет. Остальная часть полученного класса парсера выглядит нормально. (A 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

Вероятнее всего, вы имеете несоответствие версии между инструментом и библиотекой времени выполнения. Дважды проверьте это. Кроме того, IIRC вам нужно использовать версию инструмента Сэма Харвелла, если вы используете среду выполнения из NuGet, если только это не изменилось. Чтобы убедиться, возьмите NuGet, разархивируйте его и используйте инструмент, который находится внутри. –

+1

Удивительный! Я зашел в каталог * tools * пакета NuGet и заменил мой баннер ANTLR тем, что там, и теперь он отлично работает (хотя мне пришлось изменить мою команду на 'antlr4 Hello.g4 -Dlanguage = CSharp_v4_5' вместо 'antlr4 Hello.g4 -Dlanguage = CSharp'). Сообщение в качестве ответа, и я соглашусь. –

ответ

2

В пакетах NuGet используется Sam Harwell's optimized C# target вместо стандартного. Вы не можете использовать инструмент из одной версии вместе с библиотекой времени выполнения из другой, они несовместимы: посмотрите на release notes here.

Итак, если вы хотите использовать пакет NuGet для удобства, вы можете использовать инструмент, который находится внутри, - это всего лишь zip-файл.

Я не знаю, можно ли упростить этот рабочий процесс с помощью Xamarin Studio, но с Visual Studio вы можете полностью пропустить шаг генерации парсера вручную, поскольку пакет интегрируется с MSBuild для генерации кода парсера во время компиляции.

+0

@ Спасибо за исправление. У вас есть описание того, что ваши оптимизации есть, случайно? Мне было бы интересно узнать об этом больше. –

+1

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

+0

@ Спасибо спасибо! Я искал его в репозитории antlr4cs, поэтому я не смог его найти. –

Смежные вопросы