【问题标题】:Operator Associativity运算符关联性
【发布时间】:2016-09-14 22:21:37
【问题描述】:
我有以下EBNF表达式语法:
<expr> -> <term> { (+|-) <term> }
<term> -> <factor> { (*|/|%) <factor> }
<factor> -> <pow> { ** <pow> }
<pow> -> ( <expr> ) | <id>
<id> -> A | B | C
我需要确定语法是否对其运算符强制执行任何特定的关联性,或者是否必须在解析器代码中实现。从我目前所读的内容来看,它看起来不像,但我很难理解是什么导致了联想性。任何帮助将不胜感激!
【问题讨论】:
标签:
grammar
operator-keyword
bnf
associativity
【解决方案1】:
mutilates将表达式语法转换为可以用自顶向下 (LL) 语法解析的形式的标准转换已经删除了关联性信息,因为 LL 语法无法处理左-关联运算符。实际上,分析树是由 LL 文法引出的,使得所有二元运算符都是右结合的。但是,您通常可以重新关联运算符,而不会在语义操作中遇到太多麻烦。
这就是为什么乘法和求幂运算符似乎具有类似的语法产生式,尽管通常求幂是右结合的,而其他二元运算符是左结合的。
在 LR 语法中,这很明显:
<expr> -> <term> | <expr> + <term> | <expr> - <term>
<term> -> <factor> | <term> * <factor> | <term> / <factor> | <term> % <factor>
<factor> -> <pow> | <pow> ** <factor>
<pow> -> ( <expr> ) | <id>
<id> -> A | B | C
在上面的语法中,如果产生式是左递归的,则运算符是左结合的(因为运算符只能作为运算符左侧的非终结符的一部分出现)。类似地,右结合运算符具有右递归规则,原因相同。