4

使用 Flex 和 Bison,我有一个布尔查询语言的语法规范,它支持逻辑“与”、“或”和“非”操作,以及使用“()”的嵌套子表达式。

一切都很好,直到我注意到像“A和B或C和D”这样我想解析为“(A&B)|(C&D)”的查询实际上被解释为“A&(B |( C&D))”。我几乎可以肯定这是一个关联性问题,但似乎无法在任何地方找到适当的解释或示例——否则我错过了一些重要的东西。

来自 boolpars.y 的相关信息:

%token TOKEN
%token OPEN_PAREN CLOSE_PAREN
%right NOT
%left AND
%left OR

%%

query:      expression                          { ... }
            ;

expression: expression AND expression           { ... }
            | expression OR expression          { ... }
            | NOT expression                    { ... }
            | OPEN_PAREN expression CLOSE_PAREN { ... }
            | TOKEN                             { ... }
            ;

谁能找到漏洞?我不明白为什么 Bison 没有给予“或”适当的优先级。

4

3 回答 3

4

来自野牛文档:

运算符优先级由声明的行顺序决定;声明的行号越高(页面或屏幕的下方),优先级越高。

因此,在您的情况下,屏幕上的 OR 较低且优先级较高。将顺序更改为

%left OR
%left AND

(虽然我没有测试过)

于 2009-06-25T22:06:18.540 回答
1

我已经对自己的实现进行了测试,从我的测试来看,marcin 的答案是正确的。如果我将优先级定义为:

%left OR
%left AND

那么表达式 A&B|C&D 将简化为 ((A&B)|(C&D))

如果我将优先级定义为:

%left AND
%left OR

那么表达式 A&B|C&D 将简化为 ((A&(B|C))&D)

一种区分表达方式是:

true & true | true & false

前一个优先级定义会将其呈现为真,而后者会将其呈现为假。我已经测试了这两种情况,并且都按照说明工作。

仔细检查您的测试以确保。另请注意,定义优先级的是标题部分中 %left、%right 等定义的顺序,而不是您定义规则本身的顺序。如果它仍然无法正常工作,可能是你的代码中的其他一些地方搞砸了,或者你的野牛版本不同(我现在只是在黑暗中拍摄)。

于 2009-06-29T19:04:55.987 回答
1

为什么不拆分产品,就像 C-ish 语言的这个片段一样

logical_AND_expression:
    inclusive_OR_expression
    | logical_AND_expression ANDAND inclusive_OR_expression
            {$$ = N2(__logand__, $1, $3);}
    ;

logical_OR_expression:
    logical_AND_expression
    | logical_OR_expression OROR logical_AND_expression
            {$$ = N2(__logor__, $1, $3);}
    ;
于 2009-06-26T06:20:31.493 回答