运算符的结合性(形神兼备)
在编译原理中,产生式就是权威。表达式如果以某产生式进行语法分析,那么就只能按照它的方式进行表达,且不能具有二义性。但是,在表达式中有时会涉及打括号的问题。很多时候,在原表达式中打括号和原表达式等价。比如
a + b + c
等价于
(a + b) + c
但有时候却不等价 ,比如
a - b - c
不等价于
a - (b - c)
在编译原理中,括号代表了运算符的结合性,如果运算符以左侧为标准则被称为左结合的,此时在左侧打括号和不打括号等价。反之亦然。
右结合(右倾)
首先看一段产生式
right -> letter = right | letter
letter -> a|b|...|z
翻译成通俗的语言是
right 可以具有如下形式 letter = right 或 letter
letter 可以具有如下形式 a|b|..|z
举例而言
a = b
a = b = c
对于第一个例子,可以符合right -> letter = right
而right
可以是right -> letter
,而letter->a|b|...|z
对于第二个例子,可以符合right -> letter = right
而right
是right -> letter = right
,而right
可以使right->letter
,而letter->a|b|...|z
所以上述产生式可以用于描述赋值表达式。
我们把a=b=c
表达式对应的语法分析树画出来
right
/ | \
/ | \
letter = right
| / | \
a / | \
letter = right
|
letter
|
c
可以看到语法分析树是往右侧 倾斜的,而我们的表达式a=b=c
也是以右侧为标准,为什么这么说呢?因为
a = b = c
等价于
a = (b = c)
这里发现对于运算符=
而言,其结果以右侧为标准,把括号=
右侧的表达式打上括号与原表达式等价。
左结合(左倾)
我们回到语法分析树的章节,看看表达式9-5+2
对应产生式
list -> list + digit | list - digit | digit
digit -> 0|1|2|3|4|5|6|7|8|9
的语法分析树是怎样的?
list
/ | \
/ | \
list + digit
/ | \ |
/ | \ 2
list - digit
| |
digit 5
|
9
我们可以看到语法分析树向左倾斜,同样,我们也可以看到
9-5+2
等价于
(9-5)+2
也就是说对运算符+
而言,是以左侧为标准。
结论
形状
当表达式对应产生式的语法分析树左倾时,表达式以运算符左侧为主,等价于括号打在运算符左侧表达式。反之,当表达式对应产生式的语法分析树右倾时,表达式以运算符右侧为主,等价于括号打在运算符右侧表达式。
产生式
右倾产生式
right -> letter = right | letter
letter -> a|b|...|z
左倾产生式
list -> list + digit | list - digit | digit
digit -> 0|1|2|3|4|5|6|7|8|9
可以看到当产生式头部
在产生式体
中位于运算符左侧 时,以左侧为标准。反正,当产生式头部
在产生式体
中位于运算符右侧时,以右侧为主。
总之,产生式决定了运算符的结合性。