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

时间:2014-07-06 20:47:16

标签: parsing grammar ebnf peg grako

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


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

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

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

identifier 
    = 
    ?/\w+/? 
    ;

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

anIdentifier: coverpoint another_identifier;

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

我可以按如下方式重新编写规则,

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

但我想知道:

  1. 这是有意的,
  2. 如果有更好的语法?

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

1 个答案:

答案 0 :(得分:2)

它表示here在PEG中,选择运算符是有序的,以通过使用第一个匹配来避免CFG的歧义。

在您的第一个示例中

[data_type]
成功解析id,因此当它找到:而不是另一个标识符时失败。 这可能是因为[data_type]的行为与(data_type | ε)相似,因此它始终会使用第一个ID解析data_type

[data_type identifier ':' | identifier ':' ]
中,当没有第二个id时,第一个选项会失败,因此解析器会回溯并尝试第二个选择。