我正在为包含逗号运算符的C派生语言编写IntelliJ语言插件。我使用Grammar-Kit生成解析器。如果正式语法有很多嵌套的表达式制作,我使用Grammar-Kit's priority-based expression parsing重写了它们,所以我的表达式制作如下:
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树以进行函数调用,以将CommaExpression
转换为参数列表。