В следующем фрагменте показаны выражения на языке blaise.Antlr жалуется на этот контрольный пример в строке 7, поскольку правило funcall
определено ниже, чтобы содержать непустой список выражений между ().Это вывод:
line 7:11 no viable alternative at input 'pi()'
line 7:10 mismatched input '(' expecting '.'
Я понял, что грамматика неоднозначна, поэтому выбрасывается исключительное альтернативное исключение.
expr : aexpr
| bexpr
;
aexpr : NUM
| IDENTIFIER
| aexpr binop aexpr
| '(' aexpr ')'
| funcall
| '-' aexpr
;
binop : '*' | '+' | '-' | '**' | '/'
;
bexpr : aexpr relop aexpr
| bexpr ('\\/' | '/\\') bexpr
| '-' bexpr
| NUM
// | IDENTIFIER
| funcall
;
relop : '=' | '~' | '<' | '<=' | '>=' | '>'
;
funcall : IDENTIFIER '('expr (',' expr)*')'
;
Ссылка на полную грамматику .
Я действительно заинтересован в том, чтобы получить как можно больше информации от инструмента, правилам которого Antlr пытался соответствовать, прежде чем выдать исключение.Я прочитал главу об устранении ошибок и стратегии в книге.Из книги, по крайней мере, я могу найти, что можно переопределить reportNoViableAlternative
как:
public class MyErrorStrategy extends DefaultErrorStrategy {
@Override
public void reportNoViableAlternative(Parser parser,
NoViableAltException e)
throws RecognitionException
{
// ANTLR generates Parser subclasses from grammars and
// Parser extends Recognizer. Parameter parser is a
// pointer to the parser that detected the error
String msg = "can't choose between alternatives"; // nonstandard msg
parser.notifyErrorListeners(e.getOffendingToken(), msg, e);
}
}
Можно ли построить отсюда и получить правила, которые Antlr пытался соответствовать?