Я пытаюсь использовать 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.
Вероятнее всего, вы имеете несоответствие версии между инструментом и библиотекой времени выполнения. Дважды проверьте это. Кроме того, IIRC вам нужно использовать версию инструмента Сэма Харвелла, если вы используете среду выполнения из NuGet, если только это не изменилось. Чтобы убедиться, возьмите NuGet, разархивируйте его и используйте инструмент, который находится внутри. –
Удивительный! Я зашел в каталог * tools * пакета NuGet и заменил мой баннер ANTLR тем, что там, и теперь он отлично работает (хотя мне пришлось изменить мою команду на 'antlr4 Hello.g4 -Dlanguage = CSharp_v4_5' вместо 'antlr4 Hello.g4 -Dlanguage = CSharp'). Сообщение в качестве ответа, и я соглашусь. –