编译原理的文法和语言总结与梳理
梳理文法和语言的内容,理解与总结。
我们都知道,一种语言必定他的文法去描述,它的完整定义包括语法和语义两个方面。语言和语法是指一组规则,用它可以形成和产生一个合适的程序。目前广泛使用的是上下文无关文法,也就是用上下文无关文法作为程序设计的描述工具,比如用A:=B+C表示是一个合法的赋值语句,则A:=B+就不是合法的赋值语句。
什么是文法?文法相当于语言学(人类语言)中的语义分析,即分析一个句所表示的含义。它是产生中间代码或目标代码的依据。
用EBNF(EBNF是一种称为扩展巴克斯范式的形式描述)表示就是:<句子> ::= <主语><谓语>
<主语> ::= <代词>< 名词>
<代词>::= 我 | 你 | 他
<名词>::= 王明 | 大学生 | 工人 | 英语
<谓语> ::= <动词><直接宾语>
<动词> ::= 是 | 学习
<直接宾语> ::=<代词> |<名词>
(1)文法的形式化定义:
- G=(VT , VN , P , S)
- VT:终结符集合,终结符是文法所定义的语言的基本符号,有时也称为token。
- VN:非终结符集合,非终结符是用来表示语法成分的符号,有时也称为"语法变量",可以推出其它的语法成分
- P:产生式集合
- S:开始符号
(2)符号串运算:
- 符号串的连接:εx=xε=x;
- 集合的乘积:AB={xy|x∈A,y∈B};{ε}A=A{ε}=A;
- 符号串的幂运算:x=abc,x^2=abcabc;
- 集合的幂运算
正闭包A+与闭包A*:A*={ε}∪A+
(3)文法分类:
(4)语言的定义与运算
语言:在某一确定字母表上的特定符号串的集合。 空集ε,集合{ ε }也是符合此定义的语言。
语言运算举例:
- L∪D 全部字母和数字的集合
- LD 由一个字母后跟一个数字组成的所有符号串的集合
- L4 由4个字母组成的所有符号串的集合
- L* 由字母组成的所有符号串(包括)的集合
- L(L∪D)* 以字母开头,后跟字母、数字组成的所有符号串的集合
- D+ 由一个或若干个数字组成的所有符号串的集合
(5)句型、句子和语言:
- 句型:S=*>x, x∈(Vn∪Vt)*,其中S=*>x为广义推导。
- 句子:S=*>x, x∈Vt*,其中S=*>x为广义推导,x必须是终结符的闭包(可为ε)。
- 语言:L(G[S])={x|S=+>x且x属于Vt*},其中S=+>x为推导,至少使用一次规则。
(6)语法树求短语、简单短语和句柄:
- 短语:子树的末端结点形成的符号串。
- 简单子树:只有一层分支的子树。
- 直接短语(简单短语):简单子树的末端结点形成的符号串。
- 句柄:子树中最左边的那棵只有父子两代的子树的所有叶结点自左至右排列起来,就是该句型的句柄。
(7)语义的二义性
如果文法G中的某个句子存在不只一棵语法树,则称该句子是二义性的。如果文法含有二义性的句子,则称该文法是二义性的。
尝试写出PL/0 语言的文法。
EBNF 表示的符号说明。
- ‘< >’用左右尖括号括起来的中文字表示语法构造成分,或称语法单位,为非终结符。
- ‘::=’该符号的左部由右部定义,可读作“定义为” 。
- ‘|’表示“或”,为左部可由多个右部定义。
- ‘{ } ’表示花括号内的语法成分可以重复。在不加上下界时可重复 0 到任意次数,有上下界
- 时为可重复次数的限制。
- ‘[ ]’表示方括号内的成分为任选项。
- ‘( )’表示圆括号内的成分优先。
- 上述符号称“元符号” ,定义文法用到上述符号作为文法符号时需要引号 ‘’括起。
PL/0 语言文法的 EBNF 表示:
- <程序 >::=< 分程序 >.
- <分程序 >::=[< 常量说明部分 >][< 变量说明部分 >][< 过程说明部分 >]< 语句 >
- <常量说明部分 >::=CONST< 常量定义 >{,< 常量定义 >};
- <常量定义 >::=<标识符 >=< 无符号整数 >
- <无符号整数 >::=< 数字 >{< 数字 >}
- <变量说明部分 >::=VAR< 标识符 >{,< 标识符 >};
- <标识符 >::=< 字母 >{< 字母 >|<数字 >}
- <过程说明部分 >::=< 过程首部 ><分程序 >{;< 过程说明部分 >};
- <过程首部 >::=PROCEDURE< 标识符 >;
- <语句 >::=< 赋值语句 >|<条件语句 >|<当型循环语句 >|<过程调用语句 >|<读语句 >|<写语句 >|<复合语句 >|<空 >
- <赋值语句 >::=<标识符 >:=< 表达式 >
- <复合语句 >::=BEGIN< 语句 >{;< 语句 >}END
- <条件 >::=< 表达式 ><关系运算符 ><表达式 >|ODD< 表达式 >
- <表达式 >::=[+|-]< 项>{< 加法运算符 ><项>}
- <项>::=< 因子 >{< 乘法运算符 ><因子 >}
- <因子 >::=< 标识符 >|<无符号整数 >| ‘(’<表达式 > ‘)’
- <加法运算符 >::=+|-
- <乘法运算符 >::=*|/
- <关系运算法 >:===|#|<|<=|>|>=
- <条件语句 >:=IF< 条件 >THEN< 语句 >
- <过程调用语句 >::=CALL< 标识符 >
- <当型循环语句 >::=WHILE< 条件 >DO< 语句 >
- <读语句 >::=READ ‘(’<标识符 >{,< 标识符 >} ‘)’
- <写语句 >::=WRITE ‘(’<表达式 >{,< 表达式 >} ‘)’
- <字母 >::=a|b|,, |X|Y|Z
- <数字 >::=0|1|2|,, |8|9