问题
I have the following EBNF expression grammar:
<expr> -> <term> { (+|-) <term> }
<term> -> <factor> { (*|/|%) <factor> }
<factor> -> <pow> { ** <pow> }
<pow> -> ( <expr> ) | <id>
<id> -> A | B | C
I need to determine if the grammar enforces any particular associativity for its operators, or if that would have to be implemented in the parser code. From what I have read so far, it doesn't look like it does, but I am having a hard time understanding what causes associativity. Any help would be greatly appreaciated!
回答1:
The standard transformation which mutilatesconverts an expression grammar into a form which can be parsed with a top-down (LL) grammar has already removed associativity information, because the LL grammar cannot cope with left-associative operatord. In effect, the parse tree is nduced by an LL grammar makes all bi ary operators right-associative. However, you can generally re-associate the operators without too much trouble in a semantic action.
That's why the multiplication and exponentiation operators seem to have analogous grammar productions, although normally exponentiation would be right-associative while the other binary operators are left-associative.
In an LR grammar, this would be evident:
<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
In the above grammar, an operator is left-associative if the production is left-recursive (because the operator can only occur as part of the non-terminal on the left of the operator). Similarly, the right associative operator has a right-recursive rule, for the same reason.
来源:https://stackoverflow.com/questions/39500543/operator-associativity