Я пытаюсь показать ANTLR
ошибок пользователям путем внедрения BaseErrorListener
ошибка ANTLR не всегда «реальной альтернативы на входе»
public class CustomErrorListener :BaseErrorListener
{
public override void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
{
List<string> stack = ((Parser)recognizer).GetRuleInvocationStack().ToList();
stack.Reverse();
Debug.WriteLine("rule stack: " + stack);
Debug.WriteLine("line " + line + ":" + charPositionInLine + " at " + offendingSymbol + ": " + msg);
}
}
Но я всегда получаю ошибку no viable alternative at input
со следующей грамматикой
prog : expr+ EOF;
expr : COLUMN LESSTHAN DECIMAL BIGGERTHAN DECIMAL # range
| COLUMN BIGGERTHAN DECIMAL LESSTHAN DECIMAL # inversedRange
| COLUMN operator DECIMAL # simple
;
operator : LESSTHAN | BIGGERTHAN | EQUALS;
COLUMN : 'all'? ('column' | 'otherColumn')
DECIMAL : [0-9]+ '.'? [0-9]*;
LESSTHAN : '<' | '<=';
BIGGERTHAN : '>' | '>=';
EQUALS : '=';
WS : [ \r\n\t] -> channel(HIDDEN);
Если я типа column >
я ожидал бы ошибку, как decimal is missing
вместо no viable alternative at input column >
Это проблема с моей грамматикой?
EDIT
Я спрашиваю это потому, что с моим привет мир грамматики, я могу получить другие ошибки, как token recognition error
если я типа 2 + e
. Я предположил бы, что с моей грамматикой, если я типом column > d
/*
* Parser Rules
*/
prog: expr+ ;
expr : expr op=('*'|'/') expr # MulDiv
| expr op=('+'|'-') expr # AddSub
| INT # int
| '(' expr ')' # parens
;
/*
* Lexer Rules
*/
INT : [0-9]+;
MUL : '*';
DIV : '/';
ADD : '+';
SUB : '-';
WS
: (' ' | '\r' | '\n') -> channel(HIDDEN)
;
Тогда я не понимаю, почему я не получаю ошибку, например, «ошибка распознавания маркера», если я набираю столбец> d. Независимо от того, что я набираю, я всегда получаю отсутствие жизнеспособной ошибки. – Marc
Поскольку отсутствует ошибка распознавания токена - lexer закончил без ошибок, поэтому все токены распознаются и генерируются. Это синтаксический анализатор не смог найти жизнеспособный alt, чтобы соответствовать последовательности токенов, соответствующей входному тексту, который он сообщает. Если вы хотите изменить или добавить к сгенерированному тексту, добавьте ErrorListener в Parser, не печатайте 'msg', анализируйте поток токенов в точке ошибки и печатайте то, что считаете значительным. Если это не ответит на ваш вопрос, объясните, почему вы думаете, что вам нужно получать что-то другое и откуда. – GRosenberg
Спасибо. Я знаю, что ты прав, но видишь мое редактирование. В чем разница между двумя грамматиками. С моим миром привет, я получаю другие ошибки. – Marc