【问题标题】:Antlr Missing token errorAntlr 缺少令牌错误
【发布时间】:2011-11-20 23:17:44
【问题描述】:

我正在使用 antlr 生成我的解析器,但我想覆盖一些错误报告。目前,如果我给出一些不正确的语法,例如缺少标记,antlr 会给出错误“line 1:11 missing TYPE at '.'”

但是我找不到这个错误是通过哪种方法输出的。正如我最初认为的那样,它不是在 reportError() 方法中。有谁知道消息是在哪里生成的?

谢谢!

【问题讨论】:

    标签: parsing antlr token


    【解决方案1】:

    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 =)
    

    如您所见,自定义错误消息正在打印到控制台。

    编辑

    像“没有可行的选择......”这样的警告是词法分析器中的问题,而不是解析器中的问题。当词法分析器遇到您在语法中没有考虑到的字符(或者至少不是正确的标记)时,就会发生这种情况。

    假设您解析输入 a = 123:(注意末尾的 : 而不是 ;)。词法分析器现在将产生“没有可行的替代方案......”警告,因为我没有为 : 定义任何标记。

    解决此类错误的一个简单方法是在词法分析器语法的末尾添加一条“包罗万象”规则,该规则将匹配之前任何词法分析器规则不匹配的任何字符。每当这样的“包罗万象”规则匹配时,您只需在该规则的 @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: ':'
        ...
    

    【讨论】:

    • 感谢您的回答。覆盖此方法确实可以解决某些错误,但它仍然会为某些错误输出 Antlr 错误。例如'line 1:39 在字符'$' 处没有可行的替代方案。我们可以覆盖这个吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 2017-04-12
    • 1970-01-01
    • 2011-08-16
    • 2021-12-28
    • 2021-08-28
    • 2018-07-04
    相关资源
    最近更新 更多