【问题标题】:JavaCC lookahead option doesn't workJavaCC 前瞻选项不起作用
【发布时间】:2014-07-17 10:59:35
【问题描述】:

我使用的是 JavaCC 6.0,由于以下选择冲突,我需要将前瞻选项设置为 2:

double Func() :
{}
{
    <STRING> "(" ( (<STRING> | Expression() ) "," )*  ")"
}

存在冲突是因为 Expression() 可以以 &lt;STRING&gt; 开头,而我得到“考虑使用前瞻 2 进行早期扩展。”

所以我将前瞻选项更改为
options { LOOKAHEAD = 2; FORCE_LA_CHECK = true; ...}

但我仍然收到相同的警告,并且解析器在需要检测表达式而不是字符串时失败。

是我做错了什么还是前瞻选项不起作用?

【问题讨论】:

    标签: parsing javacc lookahead


    【解决方案1】:

    我从不使用除 1 之外的全局设置 LOOKAHEAD。相反,我会在需要的地方使用局部前瞻。在您的情况下,我会执行以下操作

    double Func() :
    {}
    {
        <STRING>
        "("
        ( 
             ( LOOKAHEAD( <STRING> "," )
               <STRING>
             | Expression()
             )
             ","
        )*
        ")"
    }
    

    在最后一个参数之后需要一个逗号是相当奇怪的。如果你不想这样,你可以这样做

    double Func() :
    {}
    {
        <STRING>
        "("
        ( 
             ( LOOKAHEAD( <STRING> ("," | ")") ) <STRING> | Expression() )
             (  ","
                ( LOOKAHEAD( <STRING> ("," | ")") ) <STRING> | Expression() )
             )*
    
        )?
        ")"
    }
    

    然而,在上面的两个 sn-ps 中,这些前瞻规范违反了 FAQ 4.8 中的建议,即由句法前瞻规范扫描的标记都应该被选择所消耗。如果您曾经在前瞻规范中使用 func() 本身,这可能是一个问题。对于第一种语法,这很容易处理:像这样分配逗号

    double Func() :
    {}
    {
        <STRING>
        "("
        ( 
             ( LOOKAHEAD(<STRING> "," )
               <STRING> ","
             | Expression() ","
             )
        )*
        ")"
    }
    

    对于第二种语法(最后一个参数后没有逗号的语法),您可以像这样使用递归:

    double Func() :
    {}
    {
        <STRING> "("  ( ")" | Args() )
    }
    
    void Args() :
    {}
        LOOKAHEAD(<STRING> ("," | ")" )
        <STRING>
        ("," Args() | ")" )
    |   
        Expression()
        ("," Args() | ")" )
    }
    

    递归版本的另一个好处是它比迭代版本的重复更少。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多