JetBrains / Grammar-Kit

Grammar files support & parser/PSI generation for IntelliJ IDEA
Other
704 stars 126 forks source link

Wrong priority for distfix operator with Pratt parser #353

Open bourguet opened 8 months ago

bourguet commented 8 months ago

For the grammar

{
    extends(".*_expr")=expr
}
File ::= expr*

expr ::= mult_expr | postfix_expr | primary_expr
mult_expr ::= expr '*' expr
postfix_expr ::= expr '(' expr ')'
primary_expr ::= ID

the generated code and the preview report an error for input a(b*b). If I replace

postfix_expr ::= expr '(' expr ')'

by

postfix_expr ::= expr '(' index ')'
index ::= expr

the input is accepted. The issue seems to be in the generated code:

  public static boolean expr_0(PsiBuilder b, int l, int g) {
    ...
      else if (g < 1 && consumeTokenSmart(b, OPEN_PAR)) {
        r = report_error_(b, expr(b, l, 1));
        r = consumeToken(b, CLOSE_PAR) && r;
        exit_section_(b, l, m, POSTFIX_EXPR, r, true, null);
      }
    ...
    return r;
  }

I'd have expected:

        r = report_error_(b, expr(b, l, -1));

as we are matching CLOSE_PAR afterwards. (If there had been a third expression -- let's say ternary_expr ::= expr '?' expr ':' expr -- then that third expression should be parser with g=1 or whatever the priority for the rule is, but priority shouldn't play a role for the middle expression).