JetBrains / Grammar-Kit

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

exit section in sub-rule #299

Closed davidhorac3 closed 2 years ago

davidhorac3 commented 2 years ago

Hello, After a year I've started language plugin again and I've hit an issue after updating grammar-kit in Intellij.

I have rules (shortened versions):

classVarDecl_tl ::= VAR classVarId_nmi typed? {pin=1 recoverWhile=topLevelDecl_r}
classVarId_nmi ::= IDENTIFIER // This one is not shortened... this is all it has, just to name IDENTIFIER as separate rule

Issue seems to be, that this pin/recoverWhile of parent rule is now applied to child as well.

In the generated parser it now creates a line at the end of classVarId_nmi rule:

exit_section_(b, l, m, r, false, GdParser::topLevelDecl_r);

Which results in exiting the whole section, until recover_while hits so the remaining rules like typed? for example are never parsed and it simply results in unexpected token.

I've also looked into gitlab on older codes -> those a year back and the generated parser looks little bit different and does not have that exit_section code.

For comparison, there a new generated Parser code:

public static boolean classVarId_nmi(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "classVarId_nmi")) return false;
    boolean r;
    Marker m = enter_section_(b, l, _NONE_, CLASS_VAR_ID_NMI, "<class var id nmi>");
    r = consumeToken(b, IDENTIFIER);
    exit_section_(b, l, m, r, false, GdParser::topLevelDecl_r);
    return r;
  }

And there's the old one:

public static boolean classVarId_nmi(PsiBuilder b, int l) {
    if (!recursion_guard_(b, l, "classVarId_nmi")) return false;
    if (!nextTokenIs(b, IDENTIFIER)) return false;
    boolean r;
    Marker m = enter_section_(b);
    r = consumeToken(b, IDENTIFIER);
    exit_section_(b, m, CLASS_VAR_ID_NMI, r);
    return r;
  }

The newly generated parser falls too early into recover_while branch... even though the rule classVarId_nmi exits with true result, sucessfully parsing but as it falls into recover, it eats a lot more tokens, than it's suppose to.

Is there some new approach or what might be causing this issue?

There's also possibility that I've messed something a long ago and didn't commit...

davidhorac3 commented 2 years ago

Ah... finally after another try i figured it out.

Just at the rule above classVarDecl_tl I had a syntax error... kind of. I had twice on the same row code like this:

{pin=1 recoverWhile=topLevelDecl_r} {pin=1 recoverWhile=topLevelDecl_r}

And it caused that weird behaviour without giving a syntax error.