运算符的优先级(规矩是人定的)
什么是经典?经典就是理论不随时间变迁而变化。《东方不败》中的很多台词让人时不时想起来振聋发聩。比如
很多事情不是自己想的那样,规矩是人定的。
舔狗和有思想
从小到大,我们都学过数学运算时要先乘除后加减,谁定的?
舔狗说:“老师讲的都是对的,所以这样!”有思想的人会说:“真的这样?”
一张升学试卷决定人生,舔狗继续升学,有思想的人如果不妥协就不会再有机会深造,但是,心中的疑问解决了吗?
怎么定义先乘除后加减
先乘除后加减的本质就是运算符的结合性
9+5*2
等价于
9+(5*2)
这里要注意一个问题,无论是+
,-
,*
,/
都是左结合的。
因此加减法的产生式为
list -> list + digit | list - digit | digit
digit -> 0|1|2|3|4|5|6|7|8|9
乘除法的产生式为
list -> list * digit | list / digit | digit
digit -> 0|1|2|3|4|5|6|7|8|9
现在问题是如何把上述两个产生式混合在一起,并且符合先乘除后加减
改造产生式
首先,我们要把list
分开表示。比如,
对于加减法的产生式改造为
expr -> expr + digit | expr - digit | digit
digit -> 0|1|2|3|4|5|6|7|8|9
对于乘除法的产生式改造为
term -> term * digit | term / digit | digit
digit -> 0|1|2|3|4|5|6|7|8|9
合并产生式
对于加减法产生式进一步改造为运算符的右操作数可为乘除法或者数字的。
expr -> expr + term | expr - term | term
发现了吗?现在这样的产生式可以描述这样一个表达式了
9-5*2
而且,term
必须优先于expr
,即先乘除后加减
终结版
除了先乘除后加减之外,我们还要考虑加减法在使用括号时可以先加减后乘除,因此改造上述的产生式为
expr -> expr + term | expr - term | term
term -> term * factor | term / factor | factor
factor -> digit | (expr)
digit -> 0|1|2|3|4|5|6|7|8|9
规律
为了完成优先级计算,考虑上述的产生式用到了factor
,term
和expr
三个非终结符
,我们在三者中找一下规律
-
factor
factor不能被任何运算符分开,只能放在运算符的左侧或右侧。如果用括号括起来则表示不被其分开
-
term
只能被高优先级运算符分开,不能被低优先级运算符分开