Antlr消除左递归心得

    Antlr的LL(*)文法不支持左递归,虽然Antlrworks提供了一些自动消除左递归的功能,但是也不是很好用。另外,很多文法文件都包含了(大量的)左递归,比如C99标准里的

Grammar

postfix-expression:
    primary-expression
    postfix-expression [ expression ]
    postfix-expression ( argument-expression-listopt )
    postfix-expression . identifier
    postfix-expression –> identifier
    postfix-expression ++
    postfix-expression --
    ( type-name ) { initializer-list }
    ( type-name ) { initializer-list ,}

    老夫总结一些转换模板分享给大家

左递归

基本型 1

A : b                 

     A b

      to

      A : b+

       以C99标准里的编译单元举例子:

translation_unit:
        external_declaration
        translation_unit external_declaration

     显然  translation_unit 就是 A,  external_declaration 就是 B,套用模板后

      translation_unit : external_declaration +

 
基本型 2

A :  b

      c
      A b

      to

A : (b | c) (b)*

 

基本型 3

A : b     

     c
     A e
     A f

     to

A : (b | c) (e | f)*

其实就是 类型1 和 类型2的扩展,以C99标准里的direct_declarator举例子,这个例子绝对够复杂:

direct_declarator:
        identifier
        ( declarator )
        direct_declarator [ type_qualifier_list ? assignment_expression ? ]
        direct_declarator [ static type_qualifier_list ? assignment_expression ]
        direct_declarator [ type_qualifier_list static assignment_expression ]
        direct_declarator [ type_qualifier_list ? *]
        direct_declarator ( parameter_type_list )
        direct_declarator ( identifier_list ? )

“direct_declarator” 就是 A

“identifier” 就是 b

“( declarator )” 就是 c

“[ type_qualifier_list ? assignment_expression ? ]” 就是 e

…省略

direct_declarator :

     ( identifier | ‘(‘ declarator ‘)’ )

     (    ‘[‘ type_qualifier_list ? assignment_expression ? ‘]’

         | ‘[‘ static type_qualifier_list ? assignment_expression ‘]’

        | ‘[‘ type_qualifier_list static assignment_expression ‘]’

        | ‘[‘ type_qualifier_list ? ‘*’ ’]’

        | ‘(‘ parameter_type_list ‘)’

        | ‘(‘ identifier_list ? ‘)’

     )*


扩展型

A : a       

     b
     A ? c
     A ? d
     A ? e   

     这个稍微有些麻烦,但是也很简单,先把

    A ? c

     变成    

         c

         A c

    于是变成

     A: a

         b

         c

         A c

         d

         A d

         e

         A e

    为了美观,排序一下                

      A:   a

            b         

            c

            d

            e

            A c

            A d

            A e

     最后套用 基本型 3

A:(a|b|c|d|e) (c|d|e)*

 

尾递归

尾递归基本上和左递归差不多,不多解释了…

 

基本型 1

A: b

    b A

    to

A: (b)+

 
基本型 2

A: b       

    c

    b A

    to

A: (b)(b|c)*

 

基本型 3

 

A:  a        

     b
     c A
     d A

to

A: (c|d)(a|b)*

 

扩展型

 

A : a       

     b 
     c A?  
     d A?  
     e A?

     to

    A : a

         b

         c

         c A

         d

         d A

         e

         e A

    to

    A : a

         b

         c

         d

         e

         c A

         d A

         e A

    to

(c | d| e)(a | b |c |d |e)*

posted @ 2012-01-17 14:51  lovegq  阅读(3712)  评论(4编辑  收藏  举报