如何更改野牛的规则优先级



我有两个规则,其中第一个规则优先于最后一个规则,解析器无法解析我的表达式,例如ABC.DEF,它在那里期望SQL_TOKE_GETCLASSID。相反,我想要的是第二条规则。这些规则有相同的祖先和相同的左前缀,即SQL_TOKE_NAME '.'

有没有办法告诉野牛优先考虑第二条规则而不是第一条规则。

第一条规则

ecclassid_fct_spec:
SQL_TOKEN_NAME '.' SQL_TOKEN_GETECCLASSID '(' ')'
{
...
};

第二条规则

property_path:
property_path_entry
{
$$ = SQL_NEW_DOTLISTRULE;
$$->append ($1);
}
|   property_path '.' property_path_entry %prec '.'
{
$1->append($3);
$$ = $1;
}
;   
property_path_entry:
SQL_TOKEN_NAME opt_column_array_idx
{... }
;

"优先"是什么意思?如果你只想在第二条规则完全匹配的情况下匹配它,如果不想尝试匹配第一条规则,bison就不起作用。Bison是一个LALR(1)解析器,因此它会查看每个令牌,并通过状态机跟踪匹配的规则前缀集。当它与规则的末尾匹配时,它会减少该规则,除非有一个更长的规则可以匹配,在这种情况下,你会得到移位/减少冲突。在这种情况下,你可以用优先级规则强迫它选择shift或reduce,但这样做会放弃与其他可能性相关的选择,如果结果证明这个选择在以后的输入中是错误的,就没有办法回头了。

对于您的语法(片段),它需要在看到SQL_TOKEN_NAME的输入和'.'的前瞻后做出选择(它会发生移位/减少冲突)。在这一点上,它需要知道是应该将其视为property_path_entry还是ecclass_id_fct_spec的开始。但哪一个是正确的取决于'.'之后的内容,由于野牛只做一个前瞻性的标记,现在做出这个选择还为时过早。

现在有一种方法可以让野牛使用更强大的解析机制,即CAN进行更多的前瞻性分析。您可以使用%glr-parser选项来创建GLR解析器,而不是LALR(1)解析器。这本身就足以让你的语法发挥作用,只要它不含糊。但是,如果您的语法包含任何歧义,则会出现运行时失败,除非您在语法中添加必要的歧义解析注释。bison手册包含GLR模式的大量文档,因此在尝试使用它之前,您应该阅读这些文档

这个片段太小了,什么都说不出来。但是:

  1. 您可以重新定义eclassid_fct_spec。此外,为了帮助减少,您可以定义一个新节点。tmp_node:

    SQL_TOKEN_GETECCLASSID '(' ')';

  2. 我通过灵活使用状态来处理"."问题。

  3. 不确定是否可以破坏SQL_TOKEN_NAME。看起来像这样正在泛化

最新更新