1

私は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は、チェーンされている場合、右側の式で再び代入を選択する必要があります(つまり、後置と代入演算子が続きます)。

私の理解の何が問題になっているのか分かりますか?

4

1 に答える 1

1

インタプリタに入力を与えると...

ANTLRWorks のインタープリターは使用しないでください。バグがあり、あらゆるタイプの述語を無視します。デバッガーを使用してください。問題なく動作します。

入力を postfixExpression として読み取ることができる場合、postfixExpression の後の次のトークンが代入演算子の 1 つであるかどうかをチェックし、そうである場合は、ルールを assignmentExpression として解析します。

あなたは正しいです。

EDIT [解決済み] 今、私が実現できるこの解決策には別の問題があります: 割り当て式は右側の式で選択する必要があり、連鎖している場合は再び割り当てになります (つまり、接尾辞と割り当て演算子が続きます)。

それの何がいけないの?

于 2012-01-01T18:42:40.237 に答える