如何改变野牛的规则优先权?

时间:2014-01-03 11:15:34

标签: bison

我有两个规则,其中第一个优先于最后一个,解析器无法解析我的表达式,例如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
        {... }
    ;

2 个答案:

答案 0 :(得分:1)

片段太小,无法说出任何内容。但是:

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

    SQL_TOKEN_GETECCLASSID '(' ')';

  2. 我处理了“。”在flex中使用状态的问题。

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

答案 1 :(得分:1)

“优先考虑”是什么意思?如果你想匹配第二条规则只有它完全匹配,如果不匹配第一条规则,那么野牛就不会那样。 Bison是一个LALR(1)解析器,因此它会查看每个令牌并决定哪些规则前缀匹配,通过状态机跟踪。当它与规则的末尾匹配时,它会减少该规则,除非有更长的规则可以匹配,在这种情况下,您将获得转换/减少冲突。在这种情况下,您可以强制它选择shift或reduce with precedence规则,但这样做会抛弃与其他可能性相关的选择,如果事实证明选择对于以后的输入是错误的,那么就没有办法回去。

使用你的语法(片段),在看到SQL_TOKEN_NAME的前瞻'.'的输入后,需要做出选择(它会产生移位/减少冲突)。此时,它需要知道它是否应将其视为property_path_entryecclass_id_fct_spec的开头。但哪个是正确的取决于'.'之后是什么,并且由于野牛只做了一个前瞻性的标记,所以做出这个选择还为时过早。

现在有一种方法可以让野牛使用更强大的解析机制,可以做更多的前瞻。您可以使用%glr-parser选项创建GLR解析器而不是LALR(1)解析器。只要它不含糊不清,这本身就足以使你的语法有效。但是如果你的语法含有任何含糊之处,你将会遇到运行时故障,除非你在你的语法中添加必要的歧义解决annoations。野牛手册包含大量的GLR模式文档,因此您应该在尝试使用它之前阅读它。