AntlrVSIX icon indicating copy to clipboard operation
AntlrVSIX copied to clipboard

Remove indirect recursion breaks on imported GNU PL/1 grammar.

Open kaby76 opened this issue 5 years ago • 4 comments

I'm trying to import the Bison grammar for PL/1 at http://pl1gcc.sourceforge.net/ sources then fix the grammar. Among the problems in the grammar (rules with duplicate LHS symbols, no lexer symbols declared, indirect left recursion), indirect left recursion is not being fixed by the extension transform. Even after "removing", it still says it has left recursion.

kaby76 avatar Jul 07 '20 11:07 kaby76

Using the arithmetic.g4 grammar in the template, I added these few lines from the PL/1 grammar:

e : eb | '(' e ')' ;
eb : e '+' e | e '-' e;

Applying the transform resulted in this, which is correct:

e : '(' e ')' e1 ;
eb : e '+' e | e '-' e;
e1 : '+' e e1 | '-' e e1 | ;

Now, with the original PL/1 rules:

expr  : exprbase
  | '(' expr ')'
  | '(' expr ')' exprstrconst
  ;
exprbase  : expr '+' expr
  | expr '-' expr
  | expr '*' expr
  | expr '/' expr
  | expr AND expr
  | expr OR expr
  | expr CONCAT expr
  | expr POWER expr
  | expr '=' expr
  | expr '<' expr
  | expr '>' expr
  | expr LE expr
  | expr GE expr
  | expr NE expr
  | varnameref
  | exprconst
  | '-' expr
  | '+' expr
  | NOT expr
  ;

Here, after transformation, the rules for varnameref are completely mangled, which means that it thinks varnameref participates in the indirect left recursion.

kaby76 avatar Jul 07 '20 12:07 kaby76

If I remove the "| varnameref" alternative from expr, the transform "works" and I end up with this (after adding in "varnameref expr1"):

expr :
  varnameref expr1
  | exprconst expr1
  | '-' expr expr1
  | '+' expr expr1
  | NOT expr expr1
  | '(' expr ')' expr1
  | '(' expr ')' exprstrconst expr1
  ;
exprbase  :
  expr '+' expr
  | expr '-' expr
  | expr '*' expr
  | expr '/' expr
  | expr AND expr
  | expr OR expr
  | expr CONCAT expr
  | expr POWER expr
  | expr '=' expr
  | expr '<' expr
  | expr '>' expr
  | expr LE expr
  | expr GE expr
  | expr NE expr
  | varnameref
  | exprconst
  | '-' expr
  | '+' expr
  | NOT expr
  ;
expr1 :
  '+' expr expr1
  | '-' expr expr1
  | '*' expr expr1
  | '/' expr expr1
  | AND expr expr1
  | OR expr expr1
  | CONCAT expr expr1
  | POWER expr expr1
  | '=' expr expr1
  | '<' expr expr1
  | '>' expr expr1
  | LE expr expr1
  | GE expr expr1
  | NE expr expr1
  |
  ;

kaby76 avatar Jul 07 '20 12:07 kaby76

Keep in mind that last expression rules most likely are not correct because '+' and '-' have a similar priority but in your case, '+' has more priority than '-'.

KvanTTT avatar Jul 08 '20 10:07 KvanTTT

Keep in mind that last expression rules most likely are not correct because '+' and '-' have a similar priority but in your case, '+' has more priority than '-'.

Thanks. An easy rewrite for this instance. The import of the bison grammar doesn't take precedence and associativity rules into account. Something I need to add. https://github.com/kaby76/AntlrVSIX/issues/72

kaby76 avatar Jul 08 '20 10:07 kaby76