运算符优先级:为什么用这种方式解析一元运算符?

时间:2019-04-22 16:41:28

标签: parsing compiler-construction

我跟着鲍勃·尼斯特罗姆(Bob Nystrom)的伟大著作《工艺翻译》。

如果这个问题对本网站来说太具体了,请告诉我-我已经尝试了好几个小时,但无法自行解决:)

Compiling Expressions章的函数unary()中,函数parsePrecedence(Precedence)是用PREC_UNARY而不是PREC_UNARY + 1调用的。

这本书解释说这是为了启用“嵌套”一元运算符。例如:--1

但是,在parsePrecedence(Precedence)中,在解析 prefix 运算符之前不会检查优先级-仅在 fix 运算符之前检查优先级。 unary是前缀解析器。

因此,将PREC_UNARYPREC_UNARY + 1传递到parsePrecedence(Precedence)似乎没有什么不同。我想念什么?

1 个答案:

答案 0 :(得分:1)

一个简单的答案就是你是对的:使用这种特定的语法,没有区别,因为没有二进制(或后缀)运算符具有优先级PREC_UNARY,并且将使用的测试为≤。

同样,常规答案是使用PREC_UNARY,因为一元前缀运算符是(必需)正确关联的。此约定来自二进制运算符,在这种情况下,您需要使用运算符的优先级加上左关联运算符的优先级(正常情况),并为右关联运算符使用运算符的优先级本身(例如乘幂和赋值)。 (分配实际上实际上要复杂一些,但我个人认为,鲍勃·尼斯特罗姆提出的解决方案比原本需要的解决方案更为复杂。)

另一个可能的答案是使用自下而上的运算符优先级解析器(Dijkstra的“ shunting yard”)代替自上而下的Pratt解析器。完全探索自下而上的解析方式已经超出了此问题的范围;只需说相同的原则就可以适用于结社。