2015-09-29 3 views
1

Я пытаюсь показать 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) 
    ; 

ответ

0

это проблема с моей грамматикой?

Нет. Проблема, если таковая имеется, заключается в понимании того, что Antlr делает в точке ошибки. В стеке правил будет отображаться последовательность успешно вызванных правил. В этом случае будет только prog, поскольку ни один из валов expr не будет полностью соответствовать (или, вероятно, ничего, поскольку даже не prog). Все, что Antlr может с уверенностью сказать, состоит в том, что, начиная с ввода column >, он не может найти ни одного какого-либо правила, которое будет соответствовать.

Лучший способ отладки этого типа ошибки - использовать стек правил, чтобы найти точку ошибки в потоке токенов и сбрасывать токены, которые следуют. Здесь сбрасываемые токены будут <COLUMN> <BIGGERTHAN> <EOF>, что делает природу ошибки прозрачной.

+1

Тогда я не понимаю, почему я не получаю ошибку, например, «ошибка распознавания маркера», если я набираю столбец> d. Независимо от того, что я набираю, я всегда получаю отсутствие жизнеспособной ошибки. – Marc

+0

Поскольку отсутствует ошибка распознавания токена - lexer закончил без ошибок, поэтому все токены распознаются и генерируются. Это синтаксический анализатор не смог найти жизнеспособный alt, чтобы соответствовать последовательности токенов, соответствующей входному тексту, который он сообщает. Если вы хотите изменить или добавить к сгенерированному тексту, добавьте ErrorListener в Parser, не печатайте 'msg', анализируйте поток токенов в точке ошибки и печатайте то, что считаете значительным. Если это не ответит на ваш вопрос, объясните, почему вы думаете, что вам нужно получать что-то другое и откуда. – GRosenberg

+0

Спасибо. Я знаю, что ты прав, но видишь мое редактирование. В чем разница между двумя грамматиками. С моим миром привет, я получаю другие ошибки. – Marc

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