【问题标题】:JavaCC custom errors cause "Expansion can be matched by empty string."JavaCC 自定义错误导致“扩展可以由空字符串匹配”。
【发布时间】:2018-05-03 16:50:10
【问题描述】:

我希望让我的 JavaCC 解析器返回比默认值更具体的自定义错误消息。

我目前的基本结构是这样的:

Foo(): {} { (A() B())+ }
A():   {} { <TOKA1> | <TOKA2> }
B():   {} { <TOKB1> | <TOKB2> }

我一直在研究如何抛出自定义错误消息,标准方法似乎是这样的:

A():   {} { <TOKA1> | <TOKA2> 
          | {throw new ParseException("Expected A, found " + getToken(1).image + ".");} }

但是,在 A 和 B 上执行此操作会导致编译器产生错误:

Expansion within "(...)+" can be matched by empty string.

这是可以理解的,因为解析器不“知道”空选项将终止解析过程。它预测它可以将空字符串匹配到无穷大。尽管如此,我找不到或想到任何其他简单的方法来引发这样的错误。实现我想要的结果的最佳方法是什么?

【问题讨论】:

    标签: error-handling javacc


    【解决方案1】:

    假设您的解析器已经通过循环进行了一次或多次行程。当下一个标记不是 TOKA1 或 TOKA2 时,您不希望解析器退出循环吗?

    例如如果你剩下的语法是

    void Start() : {} { Foo() C() <EOF> }
    

    如果输入是,你肯定不希望出现错误

     <TOKA1> <TOKB1> <TOKC> <EOF>
    

    &lt;TOKC&gt; 是一些可能位于 C 开头的标记。

    所以我的建议是

     Foo(): {} { 
        AForSure()
        B() 
        (A() B())* }
     AForSure() : {} { A() | {throw new ParseException("Expected A, found " + getToken(1).image + ".");} }
     A():   {} { <TOKA1> | <TOKA2> }
     B():   {} { <TOKB1> | <TOKB2> | {throw new ParseException("Expected B, found " + getToken(1).image + ".");} }}
    

    这可能无法为您提供所需的错误消息质量。例如。如果输入是

     <TOKA1> <TOKB1> <TOKB2> <EOF>
    

    您可能会收到错误消息“预期 C,找到 TOKB2”。因此,也许您希望将该错误更改为“预期 A 或 C,找到 TOKB2”。


    另一种方法是使用递归而不是循环。假设您的列表总是在括号中,例如,Foo 的唯一用途是在 Bar 中,而 Bar 看起来像这样

    Bar() : {} { "(" Foo() ")" }
    

    因此,您只想在点击“)”时退出 Foo 循环。其他任何事情都是错误。您可以将语法重写为

     Bar() : {} { "(" A("A") B() MoreFoos() }
    
     MoreFoos() : {} {  ")" |  A("A or ')'") B() MoreFoos() }
     A(String expected):   {} { <TOKA1> | <TOKA2> 
        | {throw new ParseException("Expected "+expected+", found " + getToken(1).image + ".");} } }
     B():   {} { <TOKB1> | <TOKB2>
        | {throw new ParseException("Expected B, found " + getToken(1).image + ".");} }}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-04
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 1970-01-01
      • 2023-03-10
      相关资源
      最近更新 更多