我正在构建一个简单的语言解析器,并且存在较低优先级前缀表达式的问题。这是一个示例语法:
E = E5
E5 = E4 'OR' E4 | E4
E4 = E3 'AND' E3 | E3
E3 = 'NOT' E3 | E2
E2 = E1 '==' E1 | E1
E1 = '(' E ')' | 'true' | 'false'
但是,如果将{#1}}用作较高优先级中缀运算符的RHS,则该语法不能正常工作,即:
NOT
这是由于true == NOT false
运算符在RHS上需要E1,这不是NOT操作。
我不确定表达这种语法的正确方法?是否仍然可以使用这种简单的递归下降方法,或者我是否需要转向更具特色的算法(分流码或优先攀爬)。
答案 0 :(得分:1)
假设以下输入和预期的解析是正确的:
true == NOT false
(true == (NOT false))
NOT true == false
(NOT (true == false))
NOT true == NOT false
(NOT (true == (NOT false)))
这是一个(ANTLR4)语法,可以解决这个问题:
grammar Expr;
e : e5;
e5 : e4 'OR' e5 | e4;
e4 : e3 'AND' e4 | e3;
e3 : 'NOT' e3 | e2;
e2 : e1 '==' e3 | e1;
e1 : '(' e ')' | 'true' | 'false';
S : [ \t\r\n] -> skip;
Parses ANTLR创建:
答案 1 :(得分:0)
您的语言也(不必要地)含糊不清。修复也可以帮助您解决此问题。
此处,D
是“disjunction”的简写,C
表示连词,N
表示否定,P
表示主要,E
表示相等。
D = C | C 'OR' D
C = N | N 'AND' C
N = E | 'NOT' N
E = P | P '==' P
P = '(' E ')' | 'true' | 'false'
答案 2 :(得分:-2)
也许使用波兰表示法?
E = E5
E5 = 'OR' E4 E4 | E4
E4 = 'AND' E3 E3 | E3
E3 = 'NOT' E3 | E2
E2 = '==' E1 E1 | E1
E1 = '(' E ')' | 'true' | 'false'