Algorithm 递归下降优先解析缺少前缀表达式

Algorithm 递归下降优先解析缺少前缀表达式,algorithm,parsing,operator-precedence,recursive-descent,Algorithm,Parsing,Operator Precedence,Recursive Descent,我正在构建一个简单的语言解析器,并且在低优先级前缀表达式方面存在问题。下面是一个语法示例: E = E5 E5 = E4 'OR' E4 | E4 E4 = E3 'AND' E3 | E3 E3 = 'NOT' E3 | E2 E2 = E1 '==' E1 | E1 E1 = '(' E ')' | 'true' | 'false' 但是,如果将NOT用作更高优先级中缀运算符的RHS,则此语法不能正确用于NOT,即: true == NOT false 这是因为==运算符需要RHS上的E

我正在构建一个简单的语言解析器,并且在低优先级前缀表达式方面存在问题。下面是一个语法示例:

E = E5
E5 = E4 'OR' E4 | E4
E4 = E3 'AND' E3 | E3
E3 = 'NOT' E3 | E2
E2 = E1 '==' E1 | E1
E1 = '(' E ')' | 'true' | 'false'
但是,如果将NOT用作更高优先级中缀运算符的RHS,则此语法不能正确用于NOT,即:

true == NOT false
这是因为==运算符需要RHS上的E1,这不能是NOT操作


我不确定用什么正确的方式来表达这个语法?是否仍然可以使用这种简单的递归下降方法,或者我需要转移到更具特色的算法分流场或优先爬升。

可能使用波兰符号

E = E5
E5 = 'OR' E4 E4 | E4
E4 = 'AND' E3 E3 | E3
E3 = 'NOT' E3 | E2
E2 = '==' E1 E1 | E1
E1 = '(' E ')' | 'true' | 'false'

你的语言也有不必要的歧义。解决这一问题也有助于解决此问题

这里,D表示析取,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'

假设以下输入和预期分析正确:

测试1 输入:true==非false 输出:true==非false 测试2 输入:非真==假 输出:非真==假 测试3 输入:非真==非假 输出: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;
解析创建的ANTLR:

1. 2. 3.
请注意,由于从顶层重新启动计算的显式括号规则,true==NOT false不进行解析?E=E5 E5='或'E4 E4 | E4 E4='和'E3 E3 | E3 E3 E3='不是'E3 | E2 E2='='E1 E1 E1=E |'真'|'假'如果我理解正确,你不希望E==E像它不是E==E那样解析,但E==E像它不是E==E那样解析。这是可能的,但很奇怪。如果这确实是你想要的,请在问题中说得更清楚。这确实很奇怪,但这是解析E==而不是E的唯一逻辑有效的方法。注意-我已经澄清并扩展了这一点,这对解析所述语法没有帮助。==应该是中缀。好奇地问:它怎么会模棱两可?您的解决方案会有所帮助,但它会更改优先级。==应该比没有更紧密地结合,相反,你已经颠倒了。NOT 1==2应该解析为NOT==1,2,但您的将解析为==NOT 1,2。@ChrisLeishman:您的在解析true和true时是不明确的,它不知道如何对它们进行分组。至于==绑定更紧密,您可以自己修复它。。。但是我帮你修好了。为什么要投否决票否决票是因为它改变了语法而不是我想要的。但是你现在把它修好了。然而,你现在的语法不起作用,E=P | P'='P意味着在'=='的RHS中不能存在一个'not'术语,只能是'true'或'false'。克里斯曼:你猜怎么自己修复它吗?如果我猜到了,我不会问:除了考虑转移到一个不同的算法调车场或优先攀登也许。我可以看到它是如何工作的,它向我展示了我过度简化了这个例子——如果有多个中缀优先级高于非中缀优先级,那么这个问题就解决了。我会接受答案,但我还用一个更高级的示例打开了一个新的stackoverflow问题: