Bison 如何改变野牛的规则优先级?
我有两条规则,第一条规则优先于最后一条规则,解析器无法解析我的表达式,例如Bison 如何改变野牛的规则优先级?,bison,Bison,我有两条规则,第一条规则优先于最后一条规则,解析器无法解析我的表达式,例如ABC.DEFitexpectedSQL\u TOKE\u GETCLASSID。相反,我想要的是第二条规则。这些规则具有相同的祖先和相同的左前缀,即SQL_TOKE_NAME'. 有没有办法告诉野牛优先考虑第二条规则而不是第一条规则 第一条规则 ecclassid_fct_spec: SQL_TOKEN_NAME '.' SQL_TOKEN_GETECCLASSID '(' ')' { ...
ABC.DEF
itexpectedSQL\u TOKE\u 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
{... }
;
第二条规则
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
{... }
;
碎片太小,什么也说不出来。然而:
SQL_-TOKEN_-GETECCLASSID'('')代码>
SQL\u-TOKEN\u-NAME
前面有一个“,
之后做出选择(它得到一个移位/减少冲突)。此时,它需要知道是否应该将其视为属性\u路径\u条目
或ecclass\u id\u fct\u规范
的开头。但哪一个是正确的取决于后面的内容。
,由于野牛只做了一个单独的前瞻标记,现在做出选择还为时过早
现在有一种方法可以让bison使用更强大的解析机制,可以做更多的前瞻性工作。您可以使用
%glr parser
选项来创建glr解析器,而不是LALR(1)解析器。这本身就足以让你的语法有效,只要它不含糊不清。但是如果您的语法包含任何歧义,您将获得运行时失败,除非您在语法中添加必要的歧义解决注释。野牛手册包含大量关于GLR模式的文档,因此在尝试使用它之前,您应该阅读这些文档。它确实报告了该规则的冲突。这需要一些调试,但我所做的是消除歧义ecclassid\u fct\u spec
left规则实际上是一个属性路径
。所以我做了ecclassid\u fct\u spec:property\u path.'SQL\u TOKEN\u GETECCLASSID'('')
,解决了这个问题。我的更改使规则左递归,这对LALR解析器很有好处。但这个问题与flex语法比bison更相关。其中,标记太一般,不使用谓词。但不管怎样,这个问题现在似乎已经解决了。@affan:这一更改使语法更加通用——它将接受类似于标记的内容。代币GETECLASSID()
作为一个eclassif\u fct\u规范
,它可能是您想要的,也可能不是您想要的。如果您希望这些情况无效,可以在操作中添加额外的语义检查,以针对这些情况发出错误。不,这正是我想要的。但是myClass.GETECCLASSID()
只能以一个标记作为前缀。虽然属性路径可以是a.d.c
来处理我抛出的YYERROR
,但在GETECCLASSID()的情况下,请确保属性路径长度正好是一,您的第三点非常相关。我正好遇到了flex语法包含太多泛化标记的障碍,这实际上导致语法模棱两可。我想我需要使用谓词来使标记更具体。谢谢你的帮助。