Antlr 3.0 中的错误处理

发布于 2024-10-31 05:11:23 字数 2607 浏览 0 评论 0原文

当用户输入与我们定义的规则不匹配时,我需要报告自定义错误。

这是我的代码:

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 中处理异常的方式
为什么它在我的情况下不起作用:(
请帮帮我。

I need to Report customized error when ever user input does not match our defined rules.

Here is my code:

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')
 ;

But while compiling this code I am getting the following errors:

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  

What should I do? :(
I checked on net, this is how we handle exception in ANTLR 3.x
Why is it not working in my case then :(
Please help me out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怼怹恏 2024-11-07 05:11:23

“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();
}   

"Catch blocks are no longer prefixed with 'exception' keyword", so your attribute rule would be:

attribute  :
      Value1 integer1["Value1"] { System.out.println("Accepted"); }
   |  Value2 integer2["Value2"] { System.out.println("Accepted"); }
   ;
catch[Exception e] {System.out.println("General error Reported");}

Next, you have overriden lexer's reportError method, not the one of the parser (where inbound check is invoked).

To make the parser throw error instead of recovery you can copy reportError to @parser::members section and then you can get "General error Reported".

But if you want not to stop antlr's recovery mechanism, but to make error messages more informative, you can read this free excerpt from The Definitive ANTLR Reference and define getErrorMessage method:

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();
}   
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文