• 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)*

  • 相关阅读:
    C#设计模式之策略模式
    c#设计模式之单例模式
    关于分布式事务的实现梳理
    sql事务的使用及其技巧整理
    关于web系统整体优化提速总结
    .net导出excle无需任何插件,直接通过一个tablehtml实现
    ajax+ashx:实现文件的批量导出
    angularjs学习第九天笔记(指令作用域【隔离作用域】研究)
    angularjs学习第八天笔记(指令作用域研究)
    angularjs小练习(分别通过ng-repeat和ng-option动态生成select下拉框)
  • 原文地址:https://www.cnblogs.com/quixotic/p/2324653.html
Copyright © 2020-2023  润新知