Ошибка обращения в antlr 3.0 - PullRequest
1 голос
/ 07 апреля 2011

Мне нужно сообщать о пользовательских ошибках, когда пользовательский ввод не соответствует нашим определенным правилам.

Вот мой код:

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 && 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 Ответ

2 голосов
/ 26 апреля 2011

«Для блоков Catch больше нет префикса с ключевым словом« исключение »», поэтому ваше правило атрибута будет следующим:

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 лексера, а не метод парсера (гдепроверяется входящая проверка).

Чтобы выдать ошибку парсера вместо восстановления, вы можете скопировать 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 alt; 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();
}   
...