• 【转】使用EBNF相对于BNF表示的优越性


    1. 有二义性的文法(虽然考虑了运算符的结合性,但却忽略了优先级)

    expr -> expr + term
    | expr - term
    | expr * term
    | expr / term
    | term

    term -> NUMBER
    | ( expr )

    2. 有二义性的文法(虽然考虑了运算符的优先级,但却忽略了结合性)

    expr -> term + term
    | term - term
    | term

    term -> factor * factor
    | factor / factor
    | factor

    factor -> NUMBER
    | ( expr )

    3. 正确的但没有消除左递归的文法(同时考虑到了运算符的优先级和结合性)

    expr -> expr + term
    | expr - term
    | term

    term -> term * factor
    | term / factor
    | factor

    factor -> NUMBER
    | ( expr )

    4. 消除了左递归后的正确文法
    消除直接左递归的方法:
    假设原文法 A –> Aα1|Aα2...|Aαm12|...|βn

    其中,每个βi都不以A开头。然后用下面的产生式代替A产生式:

    A –> β1A'|β2A'|...|βnA'

    A' –> α1A'|α2A'|...|αmA'|ε

    这样就消除了直接左递归。

    expr –> term moreterms

    moreterms –> + term moreterms

    | – term moreterms

    | ε

    term –> factor morefactors

    morefactors –> * factor morefactors

    | / factor morefactors

    | ε

    factor –> NUMBER

    | ( expr )

    前面都是使用的BNF表示法描述的文法,下面来看一下用EBNF表示法来描述的计算器程序的文法。

    5. 使用EBNF来表述的计算器程序的文法

    expr –> term { + term }

    | term { – term }

    term –> factor { * factor }

    | factor { / factor }

    factor –> NUMBER

    | ( expr )

    在这里,花括号表示为0个或多个的意思。比如 expr –> term { + term } 就表示0个或多个"+ term”附加到左边的term上,所以表示运算符的结合性是左结合的。通过这样,运算符的结合性就很自然的表达了出来,而不用通过BNF那样需要显示的表示为 expr –> expr + term 来表示,而且在BNF里面这样的表述是有左递归的,还需要进一步的消除左递归,而消除左递归后的文法已经面目全非,失去了美感…… 最后,EBNF这样的表述的优点还在于翻译代码时可以简化代码,比如: { + term } 可以翻译为循环,而同样的在消除了左递归的BNF表示法当中,此处要多调用一个moreterms函数。

  • 相关阅读:
    MYSQL数据库——mysql的数据类型和运算符
    MYSQL数据库——表的基本操作(定义表的约束、查看表的结构、修改数据表、删除数据表)
    MYSQL数据库——mysql数据库的基本
    企业——自动化部署 ansible 中的一些常用命令及常用模块
    企业——自动化运维 ansible
    企业——saltstack自动化部署软件值JINJIA模块的使用
    企业——saltstack自动化部署软件之Grains、Pillar
    计算机网络——HTTP协议的请求方法
    JS获取option的value和text
    Redis 认识与安装
  • 原文地址:https://www.cnblogs.com/lzhitian/p/2793941.html
Copyright © 2020-2023  润新知