5

我正在为包含逗号运算符的 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转换为参数列表。

4

0 回答 0