使用PEG(Grako)解析可选项出现问题?

5

我的同事PaulS问了我以下问题:


我正在为一种现有语言(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 ';' 
    ;

但我想知道:

  1. 这是有意为之的吗?
  2. 是否有更好的语法?

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


2
我个人的看法是,确实需要调整语法以迫使 PEG 解析器首先选择最长的选项。 - Apalala
1个回答

2
在PEG语法中,选择运算符是有序的,通过使用第一个匹配项来避免CFG的歧义问题,可以在这里找到相关信息。
在你的第一个例子中,当
[data_type]
成功解析id时,如果它找到的不是另一个标识符而是:,则会失败。 这可能是因为[data_type]的行为类似于(data_type | ε),因此它将始终使用第一个id解析data_type
[data_type identifier ':' | identifier ':' ]
中,当没有第二个id时,第一个选择会失败,因此解析器会回溯并尝试第二个选择。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接