A MissingTokenException
проходит через reportError(...)
.Допустим, вы хотите проанализировать назначения, используя следующую грамматику:
grammar T;
parse : assignment EOF;
assignment : Id '=' Number ';';
Number : '0'..'9'+ ('.' '0'..'9'+)?;
Id : ('a'..'z' | 'A'..'Z')+;
Space : ' ' {skip();};
Теперь просто переопределите метод reportError(...)
следующим образом:
grammar T;
@parser::members {
@Override
public void reportError(RecognitionException e) {
System.out.println("CUSTOM ERROR...\n" + e);
}
}
parse : assignment EOF;
assignment : Id '=' Number ';';
Number : '0'..'9'+ ('.' '0'..'9'+)?;
Id : ('a'..'z' | 'A'..'Z')+;
Space : ' ' {skip();};
, а затем попытайтесь проанализировать, скажем,"= 123;"
(отсутствует Id
):
java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main "= 123;"
CUSTOM ERROR...
MissingTokenException(inserted [@-1,0:0='<missing Id>',<4>,1:0] at =)
Как видите, пользовательское сообщение об ошибке выводится на консоль.
EDIT
Ипредупреждение типа «нет приемлемой альтернативы ...» - проблема в лексере, а не в парсере.Это происходит, когда лексер встречает символ, который вы не учли в своей грамматике (или, по крайней мере, не как правильный токен).
Допустим, вы анализируете ввод a = 123:
(обратите внимание на :
в конце вместо ;
).Теперь лексер выдаст предупреждение «нет жизнеспособной альтернативы ...», потому что я не определил токен для этого :
.
. Простое решение для учета таких ошибок - добавить «catch-catch».правило "all" в конце вашей грамматики лексера, которое будет соответствовать любому символу, который не соответствует ни одному правилу лексера перед ним.Всякий раз, когда такое правило «ловить все» совпадает, вы просто выбрасываете исключение (или делаете что-то еще, конечно!) В блоке @after{...}
этого правила.
Вот демонстрационная версия:
grammar T;
@parser::members {
@Override
public void reportError(RecognitionException e) {
System.out.println("CUSTOM ERROR...\n" + e);
}
}
parse : assignment EOF;
assignment : Id '=' Number ';';
Number : '0'..'9'+ ('.' '0'..'9'+)?;
Id : ('a'..'z' | 'A'..'Z')+;
Space : ' ' {skip();};
FallThrough
@after{
throw new RuntimeException(String.format(
"Encountered an illegal char on line \%d, column \%d: '\%s'",
getLine(), getCharPositionInLine(), getText()
)
);
}
: . // match any char not matched by Number, Id or Space
;
Если вы сейчас проанализируете a = 123:
, вы увидите на консоли следующее:
Exception in thread "main" java.lang.RuntimeException:
Encountered an illegal char on line 1, column 8: ':'
...