3058 字
15 分钟
编译原理:文法、句型、句子、语言和文法的类型

Ch2: 文法和语言

一门高级语言是一个记号系统,需要定义语言和语义两部分。

1. 符号串上的运算:#

1.0 符号串的长度#

xx为一串,则x|x|xx所占字符表中,字符的个数

1.1 符号串的(固有)头和(固有)尾,(真)前缀和(真)后缀#

z=xyz = xy,则xxzz的头(前缀),注意xx可以为ε\varepsilon

xxzz的头,且xzx \ne z,则xxzz的固有头/真前缀

1.2 符号串的连接。#

xx,yy为两个符号串,z=xyz = xyz=x+y|z| = |x| + |y|

x=εx=xεx = \varepsilon x=x \varepsilon

1.3 符号串的方幂#

xnx^n表示将串xx重复连接nn

x0=εxmxnm=xnmxm=xn,nmx^0=\varepsilon \\ x^mx^{n-m}=x^{n-m}x^m=x^n,\quad n\ge m

1.4 符号串集#

定义: 如果集合<spanclass="mdsearchhit">A</span><span class="md-search-hit">A</span>中所有的元素都是定义在符号表Σ\Sigma上的符号串,则称集合<spanclass="mdsearchhit">A</span><span class="md-search-hit">A</span>为定义在字符表Σ\Sigma的符号串集合

定义两个符号串的乘积: A×B={xyxA,yB}A \times B = \{xy|x\in A,y \in B\}

{ε}×A=A\{\varepsilon\} \times A = A

已有符号集Σ\Sigma,根据集合乘积的定义,可得到集合的方幂Σn\Sigma^n

其中:

Σ0=ε\Sigma^0 = {\varepsilon}

定义闭包:

Σ=Σ0Σ1Σ2Σ3...\Sigma^*=\Sigma^0 \cup \Sigma^1 \cup \Sigma^2 \cup \Sigma^3 \cup ...

定义正闭包:

Σ+=Σ1Σ2Σ3...\Sigma^+=\Sigma^1 \cup \Sigma^2 \cup \Sigma^3 \cup ... Σ=Σ+Σ0Σ+=Σ ×Σ\Sigma ^* = \Sigma^+ \cup \Sigma^0 \\ \Sigma ^+ = \Sigma^\ \times \Sigma^*

2. 文法的定义: (VN,VT,P,SV_N,V_T,P,S)#

对于某一语言,能够使用的是语言当中的句子,如果这些句子是有穷的,对于该语言可以列出一个有限大的句子集合。

但是有的语言当中的句子是无穷的,因此需要有限数量的文法来描述无穷数量的句子。

文法: 用有穷集合描述无穷集合的工具。

文法非空有穷集合**VN,VT,PV_N,V_T,P**和一个起始符SS构成。

2.1 非终结符集VNV_N(non-terminal symbols)#

非终结符的含义是,能够继续被替换下去的符号

  • rule:

    1. 一般用尖括号“<>”扩起非终结符。

    2. 一般用大写字母表示非终结符。

2.2 终结符集VTV_T(terminal symbols)#

终结符的含义是,不能够继续被替换的符号。

  • rule:

      1. 一般不用尖括号扩起。
      1. 一般用**小写字母**表示终结符
    

2.3 规则集PP(prescriptions)#

定义:

规则(重写规则/产生式/生成式),是一种形如αβ\alpha \to \beta,α::=β\alpha ::= \beta,(α,β)(\alpha,\beta)的有序对。读作:α\alpha定义为β\beta

其中α\alpha是规则的左部,α (VNVT),且至少包含一个非终结符\alpha \in (V_N \cup V_T)^*,且至少包含一个非终结符

β\beta是规则的右部,β (VNVP)\beta \in (V_N \cup V_P)^*

2.4 识别符(开始符)SS#

定义:

识别符SS是一个非终结符,即SVNS \in V_N

  • rule: 1. 识别符SS至少需要在一条规则中的左部出现。 1. 一般第一条产生式的左部就是识别符SS 1. 文法GG还可以表示为G[S]G[S],突出识别符SS

2.5 字母表(字汇表)V#

定义:

字母表V=VNVTV = V_N \cup V_T

另外:

VNVT=V_N \cap V_T = \varnothing

{VN,VT}\{V_N,V_T\}VV的一个划分。

3. 推导#

3.1 直接推导#

定义:

若规则αβ\alpha \to \beta是文法GG的一条规则,且有δ,γV\delta,\gamma \in V^*,v,w\exist v,w满足:

v=δαγ    w=δβγv = \delta \alpha \gamma \ \ \ \ w=\delta \beta \gamma

其中δ,γ\delta,\gamma可以是空串。

则以下说法等价:

  1. vv应用规则αβ\alpha \to \beta直接推导ww
  2. ww直接归约vv
  3. wwvv直接推导
  4. vvww直接归约
  5. v=>wv => w

3.2 长度大于0的推导v+wv \xRightarrow{+} w#

定义:

如果有推导序列:

v=>w1=>w2=>=>wn=>w(n>0)v => w_1 => w_2 => \cdots => w_n => w (n>0)

则称:

  1. vv推导到ww, 长度为nn
  2. ww归约到ww
  3. v+wv \xRightarrow{+} w

3.3 长度大于等于0的推导vwv \xRightarrow{*}w#

定义:

v=w可写作v0wv = w 可写作v \xRightarrow{0} w

v+wv \xRightarrow{+} w或者v=wv = w,写作vwv \xRightarrow{*}w读作: vv推导到ww

4. 句型、句子、语言#

4.1 句型#

定义:

有文法G[S]G[S],对某一xVx \in V^*, 若xx可由识别符SS推导而来,即:

SxS \xRightarrow{*} x

则称xx为文法G[S]G[S]的句型。

Hint:

识别符SS满足SS(S=S)S \xRightarrow{*} S(S=S),但SS是一个非终结符,故SS本身是一个句型而不是句子。

4.2 句子#

定义:

有文法G[S]G[S]和文法G[S]G[S]上的句型xx,如果xx仅由终结符组成或者为空串,即:

Sxx(VT)S \xRightarrow{*} x \wedge x \in (V_T)^*

则句型xx为文法G[S]G[S]的句子。

句子是不包含非终结符的句型。

4.3 语言(Language)#

定义:

对文法G[S]G[S],

L[G]={xx(VT)Sx}L[G] = \{x| x \in (V_T)^* \wedge S \xRightarrow{*} x \}

L[G]L[G]为文法G[S]G[S]的语言。

文法G[S]G[S]的语言是该文法一切句子的集合。[包含空串]

4.4 文法的等价#

定义:

有两个文法G1[S1],G2[S2]G_1[S_1],G_2[S_2],若:

L[G1]=L[G2]L[G_1] = L[G_2]

则称文法G1G_1和文法G2G_2等价。

两个文法等价当且仅当他们能够表示的语言相同。

5. 文法的类型#

5.1 0型文法(短语文法Phrase Structure Grammar):图灵机#

定义:

对于一文法G[S]G[S]规则集PP中的规则αβ\alpha \to \beta满足:

αV并且α至少包含一个非终结符βV\alpha \in V^* 并且\alpha 至少包含一个非终结符 \\ \beta \in V^*

即是一个0型文法

任何0型语言都是递归可枚举的。任何递归可枚举集也都是0型语言。

5.2 1型文法(上下文有关文法 Context-Sensitive Grammar):线性界限自动机#

定义:

对于一个0型文法G[S]G[S],若规则集PP中的规则αβ\alpha \to \beta满足:

αββ=ε|\alpha| \le |\beta| \vee \beta = \varepsilon

此文法即是一个1型文法。

0型文法规则集中除了β=ε\beta = \varepsilon的情况,规则右部的长度不小于左部的长度,则文法为一个1型文法。

5.3 2型文法(上下文无关文法 Context-Free Grammar): 下推自动机#

定义:

对于一个0型文法G[S]G[S],对于规则集PP中的规则每一个规则αβ\alpha \to \beta,满足:

αVNβV\alpha \in V_N \\ \beta \in V^*

即每一条规则都形如AβA \to \beta,该文法为一个2型文法。

每一条规则的左部都是一个非终结符的文法就是上下文无关文法。

上下文无关文法也是上下文有关文法。

5.4 3型文法 (正规文法:左线性文法/右线性文法) : 有穷状态自动机#

定义:

对于一个文法G[S]G[S],规则集中每一条规则αβ\alpha \to \beta都满足:

α=A,AVNβ=aB β= a,BVN\alpha = A, A\in V_N \\ \beta = aB \ \vee \beta = \ a , B \in V_N

即规则形如AaA\to a或者 AaBA \to aB​。(一定有终结符,且终结符一定在左边,非终结符可有可无。)

其中aVTεa \in V_T \cup {\varepsilon}

此文法为一个3型文法,是一个右线性文法

定义:

对于一个文法G[S]G[S],规则集中每一条规则αβ\alpha \to \beta都满足:

α=A,AVNβ=Ba β= a,BVN\alpha = A, A\in V_N \\ \beta = Ba \ \vee \beta = \ a , B \in V_N

即规则形如AaA\to a或者 AaBA \to aB(一定有终结符,且终结符一定在右边,非终结符可有可无。)

此文法也是一个3型文法,是一个左线性文法

但有的规则终结符在左边,有的规则在右边的文法不是3型文法!

显然,3型文法一定是一个上下文无关文法。

5.5 语言的类型#

不同种文法产生不同种语言。

0型文法0型语言上下文有关文法上下文有关语言上下文无关文法上下文无关语言正规文法正规语言0型文法 \to 0型语言 \\ 上下文有关文法 \to 上下文有关语言 \\ 上下文无关文法 \to 上下文无关语言 \\ 正规文法 \to 正规语言

6. 上下文无关文法与语法树#

6.1 语法树#

上下文无关文法已经很足够能描述现今的一般的程序设计语言了。因此后续如果出现文法,一般指的就是上下文无关文法

定义6.1.16.1.1 语法树是一种形象地表示上下文无关文法推导过程的直观工具。也成为推导树。并且只要给定一个上下文无关文法,对于GG的任何句型,都能够构造出一棵语法树

语法树满足:

0.语法树的根节点是起始符S1.语法树的节点都是该文法的字符2.语法树的非叶子节点(有后继的节点)都是非终结符节点。语法树的终结符都是语法树的叶子节点3.非叶子节点A的直接子孙n1,n2,,nk从左到右连在一起构成了规则集P中一条规则的右部,A是左部   也就是有一条文法G的规则An1n2nk\begin{align} &0. 语法树的根节点是起始符S\\ &1. 语法树的节点都是该文法的字符\\ &2. 语法树的非叶子节点(有后继的节点)都是非终结符节点。 \Leftrightarrow 语法树的终结符都是语法树的叶子节点\\ &3. 非叶子节点A的直接子孙n_1,n_2,\cdots,n_k从左到右连在一起构成了规则集P中一条规则的右部,A是左部 \\ & \ \ \ 也就是有一条文法G的规则A\to n_1n_2\cdots n_k \end{align}

6.2 推导和语法树#

定义6.2.16.2.1 最右(左)推导: ** 如果一个推导每一次都是替换最右(左)边的非终结符,则这个推导称为最右(左)推导**。其中最右推导也被称为规范推导。由规范推导推导而来的句型称为规范句型

定义6.2.26.2.2 最左(右)归约:如果一种归约每一次都是先把最左(右)边的终结符归约为非终结符,那么这个归约就被称为最左(右)归约。其中最左归约被称为规范归约。

最左归约是最右推导的逆过程。 

一种推导就对应一棵语法树。但是一棵语法树一般对应多种推导。比如既对应最左推导也对应最右推导。

但是一棵语法树就只对应一个最右(左)推导。

6.3 语言和语法树#

把一颗语法树的叶子节点从左往右连在一起就是一个文法的句型。

一颗语法树对应一个句型。但是一个句型并不一定只对应一颗语法树。

定义6.3.16.3.1 二义文法: 如果一个文法的某一个句子对应了至少2棵语法树(2种最右推导),则称该文法是二义的。

注意: 语言的二义性和文法的二义性不一样。如果文法GG是二义的,也会存在另一个文法GG'(可能二义,也可能不是二义的)产生的语言L[G]L[G']L[G]L[G]等价。

定义6.3.26.3.2 语言的二义性: 如果产生语言LL所有上下文无关文法GG都是二义的,才称这个语言是先天二义的

已经证明: 判断一个文法是否为二义文法,和一种语言是否为二义语言都是递归不可解的。即不存在一个算法,它可以在有限步内给出任何输入的这两个问题的答案。[不存在一个算法,它可以在有限步骤内判断任何一个文法的二义性。]

如果想判定一个文法的二义性,就要找出一个句子,它对应了至少2个正规推导(2棵语法树)。

对于一个程序设计语言来说,我们希望对它的每一个语句的分析都是单一意思的,因此需要消除文法的二义性。

消除文法二义性的办法一般是:为文法的非二义性寻找一组充分条件,比如给文法规定一些运算的结合顺序,保证有的运算先进行。

STE+TTFTFF(E)i\begin{align} & S \to T | E + T \\ & T \to F|T*F \\ & F \to (E)|i \end{align}

引入中间变量FF,保证必须先归约()()里的E才能归约*

引入中间变量TT,保证只有当归约*后才能归约++

*一定比+更先结合。

7. 句型分析#

7.1 句型分析和分析算法#

定义7.1.17.1.1 句型分析是识别一个符号串是否是某个文法的句型,也就是某个推导的构造过程。

一般把完成句型分析的程序叫做分析程序或者识别程序

分析算法可以从左往右也可以从右往左分析单词。

分析算法的实现方式主要有:

  1. 自顶向下(从开始符号SS出发,不断推导到该句型)
  2. 自底向上(从该句型出发,不断归约到开始符号SS)

7.2 自顶向下的分析方法#

不断利用产生式替换最左非终结符,使匹配上目标句型第一个未被匹配的字符。

编译原理:文法、句型、句子、语言和文法的类型
http://blog.fragments.work/posts/principleofcompiling/ch2/
作者
Lixin WANG
发布于
2024-03-15
许可协议
CC BY-NC-SA 4.0