问题
Here I am having the following piece of code:
int a,b,x;
a=b=1;
x=a+++b;
Now the value of x
will be 2 as a
is first being post incremented and then it is being added to b
.
Following is the compiled byte code :
0 iconst_1
1 dup
2 istore_2 [b]
3 istore_1 [a]
4 iload_1 [a]
5 iinc 1 1 [a]
8 iload_2 [b]
9 iadd
10 istore_3 [x]
So the expression will be equivalent to x = (a++) + b
.
Now the other expression x=a++++b
, won't compile because of the maximal munch rule. It will become x = (a++) ++ b
and hence compilation error.
Is the above behavior of x=a+++b
because of the precedence of the operator ++ or because of maximal munch rule?
回答1:
Quoting from Lexical Translations:
The longest possible translation is used at each step, even if the result does not ultimately make a correct program while another lexical translation would.
Thus, the input characters a--b are tokenized (§3.5) as a, --, b, which is not part of any grammatically correct program, even though the tokenization a, -, -, b could be part of a grammatically correct program.
This would explain why
x=a+++b
is parsed as
x=(a++)+b
On the other hand, a++++b
is tokenized as a++, ++, b which causes an error.
回答2:
Maximal munch is a rule that is used in the lexer, operator precedence in the parser, and the lexer runs conceptually before the parser. Hence, x=a+++b
is turned into x=(a++)+b
because of the maximal munch rule, not operator precedence:
When the lexer sees a+++b
is will turn this into tokens [identifier a
] [double plus] [plus] [identifier b
]. The [double plus] token is due to maximal munch (take the longest match, and ++
is longer than +
). The parser can then only turn this into (a++)+b regardless of operator precedence.
回答3:
The unary operator "++" is recognized only when there is a variable to the left of the "++". When you write a+++b, the third plus is the binary operator "add", while the first operator (++) is "increment variable by 1". When you write "a++++" things fail because this is like writing a<unary increment variable by 1> <add> <add>
and there is a missing argument for the first operator. The second pair of plus signs is not recognized as an "increment variable" because (a++) is not a variable.
Now interestingly, the Java compiler does currently requires white space to properly recognize
z = a++ + ++b; // this works
z = a+++++b; // this fails
As an old compiler writer, I would expect that both constructs should be syntactically evaluated as the same (recognizing the two unary operators ++ and ++
来源:https://stackoverflow.com/questions/22013647/operator-precedence-or-maximal-munch-rule-comes-first-for-unary-operators