使用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没有给出“或”适当的优先权。
答案 0 :(得分:4)
来自野牛文档:
运算符优先级由。确定 声明的行顺序; 线号越高 声明(页面下方或 屏幕),优先级越高。
因此,在您的情况下,OR在屏幕上较低并且具有更高的优先级。 将订单更改为
%left OR
%left AND
(虽然我没有测试过)
答案 1 :(得分: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);}
;
答案 2 :(得分:1)
我已经对自己的实现进行了测试,从我的测试中,marcin's answer是正确的。如果我将优先级定义为:
%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
前一个优先级定义会将此呈现为true,而后者将其呈现为false。我已经测试了两种情况,并且都按照解释的方式工作。
仔细检查您的测试以确保。另请注意,它是标题部分中定义优先级的%left,%right等定义的顺序,而不是您定义规则本身的顺序。如果它还没有工作,也许你的代码中的其他一些区域会弄乱它,或者你的野牛版本可能不同(我现在只是在黑暗中拍摄)。