コンマ演算子を含む C 派生言語用の IntelliJ 言語プラグインを作成しています。Grammar-Kit を使用してパーサーを生成しています。正式な文法には入れ子になった式の生成が多数あるため、 Grammar-Kit の優先度に基づく式の解析を使用してそれらを書き直したので、式の生成は次のようになります。
expression ::= comma_expression
| assignment_expression
| conditional_expression
| eor_expression
| xor_expression
| and_expression
| equality_expression
| relation_expression
| add_expression
| mul_expression
| prefix_expression
| postfix_group
| primary_expression
comma_expression ::= expression ',' expression {pin=2}
// etc.
これ自体は問題なく機能しますが、文法にはコンマ式にできない式を解析する必要がある場所があります。関数呼び出しは、この一例です。
function_call_expression ::= identifier '(' ('void'|<<comma_list expression>>)? ')'
private meta comma_list ::= <<p>> (',' <<p>>)*
関数の引数をカンマ式にすることはできません。これは、次の引数をカンマで区切るとあいまいになるためです。(私が今持っている文法では、常に単一のコンマ式として解析されます。) 正式な文法では、関数の各引数が代入式でなければならないことを指定することでこれを処理します。代入式には、より優先順位の高いすべての式が含まれるためです。これは、Grammar-Kit の優先度ベースの文法では機能しません。代入式には実際に代入を含める必要があるからです。
同じことがイニシャライザにも当てはまります。コンマ式を許可すると、 のような場合にあいまいな解析につながりますint x=1, y;
。
この状況にどのように対処すればよいですか?浅い PSI ツリーを維持するために優先度ベースの解析を使い続けたいと思いますが、関数呼び出しの PSI ツリーを手動で書き直して aCommaExpression
を引数リストに変換することも避けたいと思います。