zoukankan      html  css  js  c++  java
  • 【转】使用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函数。

  • 相关阅读:
    水洼,八连杀
    友链
    万能转换字符类型到int ,int到string,string到char or char *等等
    蓝桥杯模拟赛题
    2020 03 21
    2019 12 02 reading
    CentOS 7 定时计划任务设置
    xinted &telnet
    2019 12 02 section C one
    【暖*墟】#洛谷网课1.30# 树上问题
  • 原文地址:https://www.cnblogs.com/lzhitian/p/2793941.html
Copyright © 2011-2022 走看看