Chapter 4

BNF中使用的元符号

  • { pat } 模式pat至少重复0次

  • [ pat ] 与重复出现0次或1次的模式pat匹配

  • pat1 | pat2 与pat1或pat2匹配

  • ( ) 将括号内视为一个完整的模式

    BNF表达规则

    factor : NUMBER | “(” expression “)”
    term : factor { (“*” | “/“) factor }
    expression : term { (“+” | “-“) term }

  • :左侧所写的内容能够用于表示与在:右侧所写的模式相匹配的单词序列。

factor : NUMBER | “(” expression “)”
factor(因子)意指与右侧模式匹配的单词序列。:左侧出现的诸如factor这样的符号称为非终结符或元变量。

  • :右侧的模式中也包含了若干个终结符或非终结符。

与非终结符相对的是终结符,他们是一些事先规定好的符号,表示各种单词。
NUMBER这种由大写字母组成的名称,以及由双引号”括起的诸如”(“的符号就是终结符。
NUMBER表示任意一个整型字面量单词,”(“表示一个内容为左括号的单词。

factor : NUMBER | “(” expression “)” 规则对应的定义=> factor能表示NUMBER(1个整型字面量单词),或由左括号、expression(表达式)及右括号依次排列而成的单词序列。expression是一个非终结符,第3行对其下了定义。因此,由左括号、与expression匹配的单词序列,及右括号这些单词组成的单词序列能与factor模式匹配。

如果:右侧的模式中仅含有终结符,BNF与正则表达式没有什么区别。此时,两者唯一的不同仅在于具体是以单词为单位检查匹配还是以字符为单位检查。
另一方面,如果右侧含有类似于expression这样的非终结符,与该部分匹配的单词序列必须与另外定义的expression模式匹配。非终结符可以理解为常用模式的别称,在定义其他模式时能够引用这些非终结符。模式中包含非终结符是BNF的特诊之一。

  • term : factor { (“*” | “/“) factor }

term(项)表示一种由factor与运算符*或/构成的序列,其中factor至少出现一次,运算符则必须夹在两个factor之间。由于{}括起来的模式将至少重复0次,因此,第2行的规则直译过来就是:与模式term匹配的内容,或是一个与factor相匹配的单词序列,或是在一个与factor相匹配的单词序列之后,由运算符 * 或 / 以及factor构成的组合再重复若干次得到的序列。

  • expression : term { (“+” | “-“) term }

expression表示一种由term(对term对应的单词序列)与运算符+或-构成的序列,其中term至少出现一次,运算符则必须夹在两个term之间。
结合所有这些规则,可以发现与模式expression匹配的就是通常的四则运算表达式,只不过单词的排列顺序做了修改。也就是说,与该模式匹配的单词序列就是一个expression。反之,如果单词序列与模式expression不匹配,则会发生语法错误(syntax error)。

Chapter5

自定义的语法规则

NUMBER、IDENTIFIER、STRING、OP与EOL都是终结符,分别表示整型字面量、标识符、字符串字面量、双目运算符与换行符类型。

非终结符expr(expression的缩写)用于表示表达式。

  • primary : “(” expr “)” | NUMBER | IDENTIFIER | STRING

非终结符primary(基本构成元素)用于表示括号括起的表达式、整型字面量、标识符(即变量名)或字符串字面量。这些是最基本的表达式构成元素。

  • factor : “-“ primary | primary

非终结符factor(因子)或表示一个primary,或表示primary之前再添加一个-号的组合。

  • expr : factor { OP factor }

expr(表达式)用于表示两个factor之间夹有一个双目运算符的组合。

  • block : “{“ [ statement ] { (“;” | EOL) [ statement ] } “}”

block(代码块)指的是由{}括起来的statement(语句)序列,statement之间需要用分号或换行符(EOL)分割。由于语法支持空语句,因此规则中的statement两侧写有中括号[]。
可以看到,它的结构大致与expr类似。它们都由其他的非终结符(statement或factor)与一些用于分隔的符号组合而成。

  • simple : expr

简单表达式语句是仅由(expr)构成的语句。

  • statement : “if” expr block [ “else” block ]
    | “while” expr block
    | simple

statement可以是if语句、while语句或仅仅是简单表达式语句(simple)。

  • program : [ statement ] ( “;” | EOL )

最后的program是一个非终结符,它可以包含分号或换行符,用于表示一句完整的语句。其中,statement可以省略,因此program还能用来表示空行。代码块中最后一句能够省略句尾分号与换行符,为此,分别设计了statement与program两种类型。program既可以是处于代码块之外的一条语句,也可以是一行完整的程序。