Я пытался отладить эту ошибку, но не знаю, в чем причина. Из того, что я могу сказать через трассировку стека, это происходит, когда происходит действие PopMode
. Исключение происходит, когда я начинаю ходить по дереву. Если я удалю действие PopMode
, исключений не будет, но токенизация не будет выполнена правильно. Что я делаю неправильно, когда возвращаюсь в режим по умолчанию?
Грамматика лексера:
lexer grammar BlockLexer;
P_START : '!(:' -> pushMode(P_BLOCK);
LINE_START : '!';
SEPARATOR : ',' WS* | WS+;
WS : ' ' -> channel(HIDDEN);
NEWLINE : ((RETURN_CHAR? NEWLINE_CHAR) | RETURN_CHAR) -> popMode;
mode P_BLOCK;
P_CONTENTS : (LETTER | DIGIT)+ SEPARATOR (LETTER | DIGIT)+ SEPARATOR;
fragment RETURN_CHAR : '\\r' | '\r';
fragment NEWLINE_CHAR : '\\n' | '\n';
fragment DIGIT : [0-9];
fragment LETTER : [a-zA-Z];
Грамматика синтаксического анализатора:
grammar BlockParser;
options { tokenVocab = BlockLexer; }
block : comment_line* unit_info_line? comment_line* date_line comment_line*;
p_line : P_START P_CONTENTS NEWLINE;
comment_line : LINE_START .*? NEWLINE;
Вот мой C# код для выполните разбор:
var lexer = new BlockLexer(new AntlrInputStream(text));
var parser = new BlockParser(new CommonTokenStream(lexer));
var listener = new BlockListener();
new ParseTreeWalker().Walk(listener, parser.block());
Трассировка стека:
System.InvalidOperationException
HResult=0x80131509
Message=Operation is not valid due to the current state of the object.
Source=Antlr4.Runtime
StackTrace:
at Antlr4.Runtime.Lexer.PopMode()
at Antlr4.Runtime.Atn.LexerPopModeAction.Execute(Lexer lexer)
at Antlr4.Runtime.Atn.LexerActionExecutor.Execute(Lexer lexer, ICharStream input, Int32 startIndex)
at Antlr4.Runtime.Atn.LexerATNSimulator.Accept(ICharStream input, LexerActionExecutor lexerActionExecutor, Int32 startIndex, Int32 index, Int32 line, Int32 charPos)
at Antlr4.Runtime.Atn.LexerATNSimulator.FailOrAccept(SimState prevAccept, ICharStream input, ATNConfigSet reach, Int32 t)
at Antlr4.Runtime.Atn.LexerATNSimulator.ExecATN(ICharStream input, DFAState ds0)
at Antlr4.Runtime.Atn.LexerATNSimulator.Match(ICharStream input, Int32 mode)
at Antlr4.Runtime.Lexer.NextToken()
at Antlr4.Runtime.BufferedTokenStream.Fetch(Int32 n)
at Antlr4.Runtime.BufferedTokenStream.Sync(Int32 i)
at Antlr4.Runtime.BufferedTokenStream.Consume()
at Antlr4.Runtime.Atn.ParserATNSimulator.ExecATN(DFA dfa, ITokenStream input, Int32 startIndex, SimulatorState initialState)
at Antlr4.Runtime.Atn.ParserATNSimulator.ExecDFA(DFA dfa, ITokenStream input, Int32 startIndex, SimulatorState state)
at Antlr4.Runtime.Atn.ParserATNSimulator.AdaptivePredict(ITokenStream input, Int32 decision, ParserRuleContext outerContext, Boolean useContext)
at Antlr4.Runtime.Atn.ParserATNSimulator.AdaptivePredict(ITokenStream input, Int32 decision, ParserRuleContext outerContext)
at MyLibrary.Parser.BlockParser.block() in C:\Projects\mylibrary\MyLibrary.Parser\obj\Debug\BlockParser.cs:line 143