我的同事保罗斯问我以下事项:
我正在为现有语言编写解析器(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)?
答案 0 :(得分:2)
它表示here在PEG中,选择运算符是有序的,以通过使用第一个匹配来避免CFG的歧义。
在您的第一个示例中
[data_type]成功解析id,因此当它找到
:
而不是另一个标识符时失败。
这可能是因为[data_type]
的行为与(data_type | ε)
相似,因此它始终会使用第一个ID解析data_type
。
在
[data_type identifier ':' | identifier ':' ]中,当没有第二个id时,第一个选项会失败,因此解析器会回溯并尝试第二个选择。