用PEG(Grako)解析期权的做法不尽如人意?

我的同事保罗斯问我以下事项:

我正在为现有语言(SystemVerilog – IEEE标准)编写解析器,并且规范中有一条规则,其结构与此类似:

cover_point 
    = 
    [[data_type] identifier ':' ] 'coverpoint' identifier ';' 
    ;

data_type 
    = 
    'int' | 'float' | identifier 
    ;

identifier 
    = 
    ?/\w+/? 
    ;

问题是在解析以下合法字符串时:

anIdentifier: coverpoint another_identifier;

anIdentifier与data_type(通过其标识符选项)成功匹配,这意味着Grako正在寻找其后的另一个标识符,然后失败.然后,它不会尝试在没有data_type部分的情况下进行解析.

我可以重写这条规则如下,

cover_point_rewrite  
    = 
    [data_type identifier ':' | identifier ':' ] 'coverpoint' identifier ';' 
    ;

但我想知道:

>这是故意的
>如果有更好的语法?

这是一般的PEG问题,还是工具(Grako)?

最佳答案 它说
here在PEG中,选择运算符被命令通过使用第一个匹配来避免CFG模糊.

在你的第一个例子中

[data_type]

 成功解析id,因此它在找到时失败:而不是另一个标识符.
这可能是因为[data_type]的行为类似于(data_type |ε)所以它总是用第一个id解析data_type.

[data_type identifier ':' | identifier ':' ]

 当没有第二个id时,第一个选择失败,因此解析器回溯并尝试第二个选择.

点赞