1. 梳理第二章的内容,写一篇理解与总结。
答:在本章学习内容里,我学习到了知识点如下:
(1) 文法的直观概念
汉语句子能由谓语而成,构成谓语的是动词和直接宾语,采用第一章学习的EBNF来表示构成的规则:
<句子> :: = <主语><谓语>
<主语> :: = <代语> | <名词>
<代词> :: = 我 | 你 | 他
<名词> :: = 王明 | 大学生 | 工人 | 英语
<谓语> :: = <动词><直接宾语>
<动词> :: = 是 | 学习
<直接宾语> :: = <代词> | <名词>
*把这些规则看成是一种元语言,用它描述汉语,我们将这种语言描述称为文法。
(2)符号、和符号串
a.字母表:字母表是元素的非空有穷集合,例如,∑={a,b,c},字母表中的元素称为符号,也称为符号集;根据字母表的定义,∑是字母表,它由a,b,c个元素组成。字母表中至少包含一个元素。字母表中的元素,可以是字母、数字或其他符号。
b.符号串:由字母表中的符号组成的任何有穷序列称为符号串, 例如0011110是字母表∑={0,1}上的符号串。
*如果某符号串x中有m个符号,则称为其长度为m,表示为 |x| = m,如001110的长度是6.
*允许空符号串,即不包含任何符号的符号串,用 ε 表示,其长度为0,即 |ε|=0;。
运算:
Ⅰ.字符串的头尾:如果 z = xy是一串符号串,那么x是z的头,y是z的尾,如果x是非空的,那么y是固有尾。
Ⅱ.符号串的连接:设x和y是符号串,它们的连接xy是把y的符号写在x符号之后得到的符号串。
Ⅲ.符号串的方幂:设x是符号串,把x自身连接n次得到符号串z,即z = xx....x,称为符号串x的方幂。
Ⅳ.符号串集合:如集合A中的一切元素都是某字母表上的符号串,则称A为改字母表上的符号串集合。
* 指定字母表∑之后,可用∑*表示∑上的所有有穷长的串的集合。∑*称为集合∑的闭包,而∑+ = ∑1 U ∑2....∑n称为∑的正闭包。
* ∑*具有可数的无穷数量的元素。使用一般集合论的表示符号:若x是∑*中的元素,则表示为 x ∈ ∑*,否则 x ∉ ∑* 。 对于所有的∑,有 ε ∈ ∑* 。
(3)文法和语言的形式定义
a.规则:称为重写规则、产生式或生产式,是形如 α → ß 或 α :: = ß 的 (α ,ß)有序对,其中 α 称为规则的左部,ß称为规则的右部。
b.四元组(VN,VT,P,S):VN为非终结符(或语法实体,或变量)集;VT为终结符集;P为规则( α → ß)的集合,α ∈ (VN U VT)*且至少包含一个非终结符,ß ∈ (VN U VT)*;VN,VT和P是非空有穷集。S称作识别符或开始符,它是一个非终结符。
* VN和VT不含公共的元素,即VN ∩ VT = Ø 。
*通常用V表示VN U VT ,V称为文法G的字母表或字汇表。
c.直接推导:设 α → ß 是文法G = (VN,VT,P,S)(或说是P中的一个产生式), γ 和 δ 是 V*中的任意符号,若有符号串 v、ω满足: v = γαδ, ω = γßδ;
则说v直接产生 ω,或说 ω是 v 的直接推导。
d.句型、句子: 设G[S]是一个文法,如果符号串x是从识别符号推导出来的,即有S =*> x, 则称x是文法G[S]的句型。若x仅由终结符号组成,即 S =*> x,x ∈ VT,则称x为G[S]的句子。文法描述的语言是该文法一切句子的集合。
(4)文法的类型
四种文法: a. O型文法:设G = (VN,VT,P,S),如果它的每个产生式 α → ß 是这样一种结构:α ∈ (VN U VT)* 且至少含有一个非终结符,而 ß ∈ (VN U VT)*,则G是一个O型文法。
b. 1型或上下文有关的 :设G = (VN,VT,P,S)为一个文法,若P中的每一个产生式 α → ß均满足|ß| ≥ |α|,仅仅S → ε除外,则文法G是I型或上下文有关的。
c.2型的或上下文无关的 :设G = (VN,VT,P,S),若P中的每一个产生式α → ß满足:α是一个非终结符,ß ∈ (VN U VT)* ,则文法称为2型的或上下文无关的。
d.3型文法或正规文法:设G = (VN,VT,P,S),若P中的每一个产生式的形式都是A → aB 或 A → a,其中A和B都是非终结符,a ∈ VT*,则G 是3型文法或正规文法。
(5)上下无关文法及其语法树
* 语法树(又称推导树):
给定文法 G = (VN,VT,P,S),对于G 的任何句型都能构造与之关联的语法树,该语法树需满足下列4个条件:
a.每个结点都有一个标记,此标记是V的一个符号。
b.根的标记是S。
c.若一个结点n至少有一个它自己除外的子孙,并且有标记A,则A肯定在VN中。
d.如果结点n的直接子孙从左到右的次序是结点n1,n2,....,nk,其标记分别为A1,A2,....,Ak,那么A → A1,A2....,Ak,一定是P中的一个产生式。
* 最左推导:如果在推导的任何一步 α => ß,其中α 、ß是句型,都是对α中的最左非终结符进行替换,则称这种推导为最左推导。
* 最右推导:如果在推导的任何一步 α => ß,其中α 、ß是句型,都是对α中的最右非终结符进行替换,则称这种推导为最右推导。
例如: 推导1: E => E + E => E * E + E => I * E + E => i * i + E => i * i + i
推导2: E => E * E => i * E => i * E + E => i * i + E => i * i + i
*文法的二义性:如果一个文法存在某个句子对应两棵不同的语法树,则称此文法是二义性文法,运用文法描述程序设计语言的语句成份,一般希望所给文法是非二义文法,但是,有时候采用二义性文法比非二义文法要简单的多,所以,经常用二义性文法描述程序设计语言。
2. 尝试写出PL/0 语言的文法。(或者你认为比较好的语言规则)
(1)整数n :
<无符号整数> ::= <数字>{<数字>}
n ::= 0 | 1 | 2 |... |8| 9
(2)标识符i :
<标识符> ::= <字母>{<字母>|<数字>}
<字母> ::= a | b | c | d | e | ... | w | x | y | z
<数字> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
(3)表达式e
e ::= [+|-]<项>{<加减运算符><项>}
(4)条件语句
<条件语句> ::= IF<条件>THEN<语句> <过程调用语句>::=CALL<标识符>
(5)赋值语句
<赋值语句> ::= <标识符>:=<表达式>
(6)复合语句
<复合语句> ::= BEGIN<语句>{;<语句>}END
(7)函数
<函数> ::= <类型说明><函数名><复合语句>
(8)程序
<程序> ::= <分程序>.
(9) 分程序
<分程序> ::= [<常量说明部分>][<变量说明部分>][<过程说明部分>]<语句>
(10)常量说明部分
<常量说明部分> ::= CONST<常量定义>{,<常量定义>}
(11)常量定义
<常量定义> ::= <标识符>=<无符号整数>
(12)无符号整数
<无符号整数> ::= <数字>{<数字>}
(13)变量说明部分
<变量说明部分> ::= VAR<标识符>{,<标识符>}
(14)过程说明部分
<过程说明部分> ::= <过程首部><分程序>{<过程说明部分>}
(15)过程首部
<过程首部> ::= PROCEDURE<标识符>