0

Can you help me with this example? How should i do left recursion elimination with this size? i know how to do it for simpler examples.

Expr1      ::= Number
     | String
     |  `true` 
     | `false` 
     | `undefined`            
     |  Expr1 `+` Expr1            
     |  Expr1 `-` Expr1            
     |  Expr1 `*` Expr1            
     |  Expr1 `%` Expr1            
     |  Expr1 `<` Expr1            
     |  Expr1 `===` Expr1            
     |  Ident AfterIdent            
     |  `[` Exprs `]`          
     |  `[` `for` `(` Ident `of` Expr `)` ArrayCompr Expr `]`            
     |  `(` Expr `)`

Is this the solution?

Expr1      ::= Number ExprB    
     | String ExprB    
     |  `true` ExprB       
     | `false` ExprB       
     | `undefined` ExprB                       
     |  Ident AfterIdent ExprB        
     |  `[` Exprs `]`            
     |  `[` `for` `(` Ident `of` Expr `)` ArrayCompr Expr `]`            
     |  `(` Expr `)`
ExprB      ::= ϵ
     | `+` Expr1 ExprB
     | `-` Expr1 ExprB
     | `*` Expr1 ExprB
     | `%` Expr1 ExprB
     | `<` Expr1 ExprB
     | `===` Expr1 ExprB
Ezis
  • 73
  • 8

1 Answers1

1

The trick I've learned is to introduce constructive non-terminals to get fewer grammar rules at any one spot. You'll still have some nasty expansions inherent in the language, but you can make the process easier at each step.

Scalar ::= Number | String | `true` | `false` | `undefined`
Op     ::= '+' | '-' | '*' | '%' | '<' | '==='
OpExpr ::= Expr1 Op Expr1
ParenExpr ::= 
      `[` Exprs `]`
    | `[` `for` `(` Ident `of` Expr `)` ArrayCompr Expr `]`
    | `(` Expr `)`

Expr1 ::=
      Scalar
    | OpExpr
    | ParenExpr
    | Ident AfterIdent

There are two main gains here. One is that if you're implementing the parser, the rules now more closely match the families of processing. You can take certain common actions upon the classified reductions. The second is that you can simplify your elimination of recursion: you have the same quantity of terminals to begin an Expr1, but only one rule to expand, the definition of OpExpr.

I know that I haven't completed the exercise for you, but I hope that this helps enough to get you moving. You might also want to check out operator precedence grammars: they handle some of this in elegant fashion, depending on your application.

Prune
  • 76,765
  • 14
  • 60
  • 81