私はJavaプレフィックス演算子に取り組んでいて、この動作に遭遇しました
i = +--j //does not give an error
i = -++j //does not give an error
i = ---j //gives an error
i = +++j //gives an error
なぜこうなった?
私はJavaプレフィックス演算子に取り組んでいて、この動作に遭遇しました
i = +--j //does not give an error
i = -++j //does not give an error
i = ---j //gives an error
i = +++j //gives an error
なぜこうなった?
コンパイラは、貪欲な左から右へのトークンの選択を使用します。したがって、 が表示さ+--j
れると、有効なトークンである最長のシーケンスは です。 は有効なトークンで+
は+-
ないため+
、最初のトークンとして取得されます。次に、トークンとして識別できる 2 番目に大きなもの、つまり を調べます--j
。結果は+ --j
なぜなら、それは最長の有効なトークン---j
と見なされ、次に次の有効なトークンと見なされ、@Mureinik が指摘したように有効ではないものとしてそれらをまとめようとします。--
-j
-- -j
コンパイラは、存在する演算子を認識する前に、それらを解析する必要があります。の 3 つの可能な解析を確認できます---j
。
- - -j // 3 unary - operators
-- -j // predecrement -- followed by unary -
- --j // unary - followed by predecrement --
のケース+++j
は同等であり、プレインクリメント++
と単項が+
置換されています。
Javaは、構文的に有効でない唯一の 2 番目のケースである が--
続くと解釈するのはなぜですか? -
コンパイラは一般的に貪欲です。 JLS のセクション 3.2 には次のように記載されています。
生の Unicode 文字ストリームは、順番に適用される次の 3 つの字句変換ステップを使用して、一連のトークンに変換されます。
...
結果が最終的に正しいプログラムを作成せず、別の字句変換が. 例外が 1 つあります。字句変換が型コンテキスト (§4.11) で発生し、入力ストリームに 2 つ以上の連続した > 文字があり、その後に非 > 文字が続く場合、各 > 文字をトークンのトークンに変換する必要があります。数値比較演算子 >.
(太字強調鉱山)
コンパイラは貪欲に 2 つの文字を認識し、次に来る3 番目の文字を考慮せずに、すぐにトークンで-
あると宣言します。--
-
これは、演算子の結合性や演算子の優先順位とは関係がなく、構文解析とは関係ありません。
@Mureinik で既に述べたように、明確な括弧を適切に配置すると、コンパイラはそれを正しく解析するようになります。ただし、操作の優先順位を変更するのではなく、文字を異なるトークンに分割することでこれを実現します。
式-++j
は、コンパイラの貪欲さの影響を受けません。-+
は有効なトークンではないため、 token の後に token-
が続くものとして正しく解析さ++
れ、式 についても同様です+--j
。