У меня есть простая грамматика ANLTR и сопровождающий Visitor. Все работает отлично, если вход недействителен. Если вход недействителен, ошибки проглатываются, и мой калькулятор выходит с неправильным выходом.
Я попытался внедрить прослушиватель ошибок, верхом по методу Recover
lexer и... ну... еще полдюжины других вещей сегодня. Может ли кто-нибудь показать мне, как просто выбросить ошибку, а не глотать плохие "токены"? (Я использую кавычки, потому что они не являются маркерами вообще. Символы undefined в моей грамматике.)
Действительный ввод:
1 + 2 * 3 - 4
Недопустимый ввод:
1 + 2 + 3 (4)
Я хочу бросить ArgumentException
, если парсер/лексер встречается с круглой скобкой (или любым другим символом undefined). В настоящее время недопустимые символы, похоже, просто исчезают в эфире, и парсер просто держится, как будто ничего не случилось.
Если я запустил его в консоли с помощью команды grun
, я получаю следующий вывод, поэтому он распознает недействительные токены на некотором уровне.
строка 1: 9 ошибка распознавания маркера в: '('
строка 1:11 ошибка распознавания токена в: ')'
и это получившееся дерево синтаксического анализа.
BasicMath.g4
grammar BasicMath;
/*
* Parser Rules
*/
compileUnit : expression+ EOF;
expression :
expression MULTIPLY expression #Multiplication
| expression DIVIDE expression #Division
| expression ADD expression #Addition
| expression SUBTRACT expression #Subtraction
| NUMBER #Number
;
/*
* Lexer Rules
*/
NUMBER : INT; //Leave room to extend what kind of math we can do.
INT : ('0'..'9')+;
MULTIPLY : '*';
DIVIDE : '/';
SUBTRACT : '-';
ADD : '+';
WS : [ \t\r\n] -> channel(HIDDEN);
Калькулятор:
public static class Calculator
{
public static int Evaluate(string expression)
{
var lexer = new BasicMathLexer(new AntlrInputStream(expression));
var tokens = new CommonTokenStream(lexer);
var parser = new BasicMathParser(tokens);
var tree = parser.compileUnit();
var visitor = new IntegerMathVisitor();
return visitor.Visit(tree);
}
}