消除我的语法的左递归

时间:2015-11-05 00:59:02

标签: recursion grammar transformation left-recursion

你能用这个例子帮我吗?我该怎么做这个大小的左递归消除?我知道如何做更简单的例子。

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

这是解决方案吗?

static void method1( ... ) for ( i: parameters ) print( i )
// or
static void method1( int a, ... ) for ( f=a; f < parameters.count(); f++) print( parameters[ i] );

1 个答案:

答案 0 :(得分:1)

我学到的技巧是引入建设性的非终端,以便在任何一个地点获得更少的语法规则。你仍然会在语言中固有一些讨厌的扩展,但你可以在每一步都让这个过程更容易。

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

这里主要有两个好处。一个是如果你正在实现解析器,那么规则现在更接近于处理系列。您可以对分类减少采取某些共同行动。第二,你可以简化你的递归消除:你有相同数量的终端开始 Expr1 ,但只有一个规则要扩展,OpExpr的定义。

我知道我还没有为你完成练习,但我希望这有助于让你感动。您可能还想查看运算符优先级语法:它们以优雅的方式处理其中一些,具体取决于您的应用程序。