私はD用のANTLRを使用してパーサーを実装しています。この言語はCに基づいているため、宣言と式にはあいまいさがあります。このことを考慮:
a* b = c; // This is a declaration of the variable d with a pointer-to-a type.
c = a * b; // as an expression is a multiplication.
2番目の例は代入式の右側にしか表示されないため、次のスニペットを使用してこの問題を解決しようとしました。
expression
: left = assignOrConditional
(',' right = assignOrConditional)*
;
assignOrConditional
: ( postfixExpression ('=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '~=' | '<<=' | '>>=' | '>>>=' | '^^=') )=> assignExpression
| conditionalExpression
;
assignExpression
: left = postfixExpression
( op = ('=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '~=' | '<<=' | '>>=' | '>>>=' | '^^=')
right = assignOrExpression
)?
;
conditionalExpression
: left = logicalOrExpression
('?' e1 = conditionalExpression ':' e2 = conditionalExpression)?
;
私の理解では、これであいまいさを回避するためのトリックが実行されるはずですが、テストは失敗しています。ルールassignOrConditionalから始めて、インタプリタに入力をフィードすると、NoViableAltExceptionで失敗します。入力は
a = b
b-=c
d
おそらく私は述語がどのように機能しているかを誤解しているので、誰かが私の説明をコードに修正できれば素晴らしいでしょう:入力がpostfixExpressionとして読み取れる場合、postfixExpressionの後の次のトークンが割り当て演算子の1つであるかどうかをチェックしますそうである場合は、ルールをassignmentExpressionとして解析します。(assignmentExpressionとconditionalExpressionが適切に機能することに注意してください)。次のトークンがそれらのものでない場合、それはそれをconditionalExpressionとして解析しようとします。
編集 [解決済み]このソリューションには、私が気付く可能性のある別の問題があります。assignmentExpressionは、チェーンされている場合、右側の式で再び代入を選択する必要があります(つまり、後置と代入演算子が続きます)。
私の理解の何が問題になっているのか分かりますか?