#antlr
#antlr
Вопрос:
Мне нужно сообщать о настраиваемой ошибке, когда пользовательский ввод не соответствует нашим определенным правилам.
Вот мой код:
grammar second1;
@lexer::members {
@Override
public void reportError(RecognitionException e) {
System.out.println("Throwing Exception: " e.getMessage());
throw new IllegalArgumentException(e);
}
}
@parser::members {
private boolean inbounds(Token t, int min, int max, String methodName) {
int n = Integer.parseInt(t.getText());
if(n >= min amp;amp; n <= max) {
return true;
}
else {
System.out.println("The range for value accepted by " methodName " is " min "-" max );
return false;
}
}
}
expr : SET attribute EOF;
attribute : Value1 int1:integer1["Value1"] { System.out.println("Accepted"); }
| Value2 integer2 ["Value2"] { System.out.println("Accepted"); }
;
exception[int1]:
catch[Exception e] {System.out.println("Error Reported for int1");}
exception:
catch[Exception e] {System.out.println("General error Reported");}
integer1 [String methodName] : Int { inbounds($Int,0,1000,methodName) }? ;
integer2 [String methodName] : Int { inbounds($Int,0,10000,methodName) }? ;
Int : '0'..'9' ;
SET : 'set';
Value1 : 'value';
Value2 : 'value2';
fragment WS
: (' ' | 't')
;
Но при компиляции этого кода я получаю следующие ошибки:
error(100): second1.g:26:22: syntax error: antlr: second1.g:26:22: unexpected token: int1
error(100): second1.g:29:17: syntax error: antlr: second1.g:29:17: unexpected token: :
error(100): second1.g:32:10: syntax error: antlr: second1.g:32:10: unexpected token: catch
error(100): second1.g:0:0: syntax error: assign.types: <AST>:0:0: unexpected AST node: <end-of-block>
error(100): second1.g:0:0: syntax error: assign.types: <AST>:0:0: unexpected end of subtree
error(100): second1.g:0:0: syntax error: define: <AST>:0:0: unexpected AST node: <end-of-block>
error(100): second1.g:0:0: syntax error: define: <AST>:0:0: unexpected AST node: <end-of-block>
error(100): second1.g:0:0: syntax error: define: <AST>:0:0: unexpected end of subtree
error(106): second1.g:26:27: reference to undefined rule: integer1
error(106): second1.g:27:22: reference to undefined rule: integer2
warning(105): second1.g:27:15: no lexer rule corresponding to token: Value2
warning(105): second1.g:26:15: no lexer rule corresponding to token: Value1
warning(105): second1.g:24:15: no lexer rule corresponding to token: SET
Что мне делать? : (
Я проверил в сети, именно так мы обрабатываем исключения в ANTLR 3.x
Тогда почему это не работает в моем случае: (
Пожалуйста, помогите мне.
Ответ №1:
«Блоки Catch больше не имеют префикса с ключевым словом ‘exception'», поэтому ваше правило атрибута будет:
attribute :
Value1 integer1["Value1"] { System.out.println("Accepted"); }
| Value2 integer2["Value2"] { System.out.println("Accepted"); }
;
catch[Exception e] {System.out.println("General error Reported");}
Далее, вы переопределили метод reportError lexer, а не метод синтаксического анализатора (где вызывается проверка входящих сообщений).
Чтобы заставить анализатор выдавать ошибку вместо восстановления, вы можете скопировать reportError в раздел @parser::members, и тогда вы сможете получить «Сообщение об общей ошибке».
Но если вы хотите не останавливать механизм восстановления antlr, а сделать сообщения об ошибках более информативными, вы можете прочитать этот бесплатный отрывок из окончательного справочника ANTLR и определить метод getErrorMessage:
public String getErrorMessage(RecognitionException e, String[] tokenNames)
{
List stack = getRuleInvocationStack(e, this.getClass().getName());
String msg = null;
if ( e instanceof NoViableAltException ) {
NoViableAltException nvae = (NoViableAltException)e;
msg = " no viable a< token=" e.token
" (decision=" nvae.decisionNumber
" state " nvae.stateNumber ")"
" decision=<<" nvae.grammarDecisionDescription ">>";
}
else if( e instanceof FailedPredicateException ) {
FailedPredicateException fpe = (FailedPredicateException)e;
msg = "failed predicate; token=" fpe.token
" (rule=" fpe.ruleName " predicate=" fpe.predicateText ")";
}
else {
msg = super.getErrorMessage(e, tokenNames);
}
return stack " " msg;
}
public String getTokenErrorDisplay(Token t) {
return t.toString();
}