编译原理_文法基础

概述

1956年,语言学家Chomsky提出了形式语言理论,极大的促进了程序语言的发展,也促进了编译理论的发展。编译原理的主要内容就是应用形式语言理论,它贯穿于词法分析和语法分析两个阶段。

为了更系统的理解编译过程中的分析阶段,我们需要掌握一定的语言理论,而描述一个语言的语法与结构的规则称为文法

形式描述

在深入理解编译是如何应用语言理论之前,需要先了解一些符号更方便的来描述,下面对一些符号及其定义做一些简单介绍。

  • 字母表,字符:字母表用 ∑ \sum 来表示,它是字符的非空有穷集合,字符是 ∑ \sum 中的元素。如 ∑ = { a , p , l , e } \sum=\{a,p,l,e\} ={a,p,l,e}
  • 字符串:字符串是由 ∑ \sum 组成的有穷序列。如"h"、“hi”、"hello"都是 ∑ \sum 上的字符串。
  • 字符串的长度:一般形容串长度用绝对符号来表示。如 ∣ h e l l o ∣ = 5 |hello|=5 hello=5
  • 空串:由零个字符组成的序列,空串用 ε \varepsilon ε来表示 ∣ ε ∣ = 0 |\varepsilon|=0 ε=0
  • 连接:字符串S和T的连接指将字符串T接在S后,又表示为 S ⋅ T S \cdot T ST S T ST ST。另对于 ∑ \sum 上的任何字符串S都满足 S ⋅ ε = ε ⋅ S = S ​ S \cdot \varepsilon = \varepsilon \cdot S = S​ Sε=εS=S
  • ∑ ∗ ​ \sum^*​ :指包括 ε ​ \varepsilon​ ε在内的 ∑ ​ \sum​ 所有字符串的集合
  • 字符串的幂:即把字符串 α ​ \alpha​ α自身连接n次的字符串,称为 α ​ \alpha​ α的n次幂,记为 σ n ​ \sigma ^n​ σn,一些特殊规则与集合运算相同。
  • 字符串集合运算:如设A、B代表 ∑ \sum 上的两个字符串集合。
    • 或(合并): A ⋃ B = { α ∣ α ∈ A 或 α ∈ B } ​ A \bigcup B = \{ \alpha | \alpha \in A 或 \alpha \in B \}​ AB={ααAαB}
    • 积(连接): A B = { α β ∣ α ∈ A 且 β ∈ B } ​ AB = \{ \alpha \beta | \alpha \in A 且 \beta\in B \}​ AB={αβαAβB},且也可以用逗号代替。
    • 幂: A n = A A n − 1 = A n − 1 A ( n > 0 ) A^n = A A^{n-1} = A^{n-1}A (n>0) An=AAn1=An1A(n>0),并规定 A 0 = ε A^0 = \varepsilon A0=ε
    • 正则闭包+: A + = A 1 ⋃ A 2 ⋃ A 3 ⋃ ⋯ ⋃ A n ⋃ … A^+ = A^1 \bigcup A^2 \bigcup A^3 \bigcup \dots \bigcup A^n \bigcup \dots A+=A1A2A3An
    • 闭包*: A ∗ = A 0 ⋃ A + ​ A^* = A^0 \bigcup A^+​ A=A0A+。显然又有: ∑ ∗ = ∑ 0 ⋃ ∑ 1 ⋃ ∑ 2 ⋃ ⋯ ⋃ ∑ n ⋃ … ​ \sum^* = \sum^0 \bigcup \sum^1 \bigcup \sum^2 \bigcup \dots \bigcup \sum^n \bigcup \dots​ =012n

文法与语言的形式定义

Chomsky将文法G定义为四元组: G = ( V N , V T , P , S ) G = (V_N, V_T, P, S) G=(VN,VT,P,S)

其中:

  • V N V_N VN 是非空有限集,其中每个元素都为非终结符,因此也叫做非终结符集。
  • V T V_T VT 也是非空有限集,但其中每个元素均为终结符,因此也叫做终结符集。
    • 另外, V N ⋂ V T = ∅ ​ V_N \bigcap V_T = \empty ​ VNVT=,即两者之间无公共元素
  • P 是产生式的有限集,产生式的形式是写作“ α → b e t a ​ \alpha \to beta​ αbeta”的规则,其中 α ​ \alpha​ α称为产生式左部, β ​ \beta​ β称为产生式的右部。
    • 其中, α ∈ V + \alpha \in V^+ αV+,且 α \alpha α至少含有一个非终结符。且, β ∈ V ∗ \beta \in V^* βV
    • 若干个产生式如: α → β 1 , α → β 2 , … , α → β n ​ \alpha \to \beta_1, \alpha \to \beta_2, \dots, \alpha \to \beta_n​ αβ1,αβ2,,αβn的左部相同情形时,可简写为: α → β 1 ∣ β 2 ∣ … ∣ β n ​ \alpha \to \beta_1 | \beta_2 | \dots | \beta_n​ αβ1β2βn,称作 β i ( 1 ≤ i ≤ n ) ​ \beta_i (1 \leq i \leq n)​ βi(1in) α ​ \alpha​ α的一个候选式。
  • S是文法的开始符号,至少要在一条产生式的左部中出现 S ∈ V N S \in V_N SVN

文法的分类

文法分为0型、1型、2型、3型共4种类型,它们之间的差别主要是产生式的约束不同。其中,0型文法又是基础,其余文法均基于0型之上。如2型文法的约束必须同时满足0型与2型的约束。

  • 0型文法

    G的任一产生式 α → β ​ \alpha \to \beta​ αβ ,均有 α ∈ ( V N ⋃ V T ) + ​ \alpha \in (V_N \bigcup V_T)^+​ α(VNVT)+ α ​ \alpha​ α至少含有一个非终结符,且 β ∈ ( V N ⋃ V T ) ∗ ​ \beta \in (V_N \bigcup V_T)^*​ β(VNVT)

  • 1型文法

    G的任一产生式 α → β ( S → ε 除 外 ) \alpha \to \beta (S \to \varepsilon除外) αβ(Sε) ,均有 ∣ α ∣ ≤ ∣ β ∣ |\alpha| \leq |\beta| αβ

  • 2型文法

    G的任一产生式形式 A → β A \to \beta Aβ ,均有 A ∈ V N , β ∈ ( V N ⋃ V T ) ∗ A \in V_N, \beta \in (V_N \bigcup V_T)^* AVN,β(VNVT)

  • 3型文法

    G的任一产生式形式 A → a A \to a Aa A → a B ( 或 A → B a ) A \to aB(或A\to Ba) AaB(ABa),均有 A , B ∈ V N A, B \in V_N A,BVN,另有 a ∈ V T a \in V_T aVT

从分类定义中可知,0型文法具有最少的限制,逐级递增。

其中,0型文法又称为短语文法无限制文法,它几乎对产生式没有任何限制。任何的0型语言都是递归可枚举的;反之任何递归可枚举的文法也必然是0型语言。

1型文法称为长度增加文法上下文有关文法(CSG, Context-Sensitive Grammar),这种文法意味着终结符的替换与上下文关联,并且不允许替换为 ε ​ \varepsilon​ ε。如:若 α A B → α γ β ​ \alpha AB \to \alpha \gamma \beta​ αABαγβ是1型文法的产生式,且 α , β ​ \alpha, \beta​ α,β不全为空。则非终结符A只有在左边是 α ​ \alpha​ α,右边是 β ​ \beta​ β的上下文中才能替换成 γ ​ \gamma​ γ

2型文法称为上下文无关文法(CFG, Context-Free Grammar),其非终结符的替换无需考虑上下文。

3型文法称为正规文法(RG, Regular Grammar)线性文法

另外,识别0型语言的自动机称作图灵机;识别1型语言的自动机称作线性界限自动机;识别2型语言的自动机称作下推自动机;识别3型语言的自动机称作有限状态自动机

程序语言中的语法和词法规则主要是2、3型文法。另外,还对产生式增加两点限制:

  1. 不存在 P → P ​ P \to P​ PP的产生式,因为除了增加二义性外毫无意义。
  2. 产生式中出现的非终结符 P P P必须是可达的,并且能推出终结符串,即存在并满足( ⇒ \Rightarrow 的含义见推导与直接推导): S ⇒ ∗ α P β , P ⇒ + γ , γ ∈ V T ∗ , ( α , β ∈ V ∗ ) ​ S \Rightarrow^* \alpha P \beta, P \Rightarrow^+ \gamma, \gamma \in V^*_T, (\alpha , \beta \in V^*)​ SαPβ,P+γ,γVT,(α,βV)

句子和语言的产生

上面介绍了文法的基本概况,文法本质上是用来指导语法和结构的,因此接下来就要看看如何使用文法、产生式等内容产生符合文法的语言及该过程的一些表示方法。

推导与直接推导

推导即从文法的开始符出发,反复使用产生式,将产生式左部的非终结符替换为右部的文法符号序列(展开产生式用 ⇒ ​ \Rightarrow​ 表示),直到最终产生一个终结符的序列为止。

如有产生式 α → β ∈ P , γ , δ ∈ V ∗ ​ \alpha \to \beta \in P, \gamma, \delta \in V^*​ αβP,γ,δV,则 γ α δ ⇒ γ β δ ​ \gamma \alpha \delta \Rightarrow \gamma \beta \delta​ γαδγβδ称为文法中的直接推导,并称 γ α δ ​ \gamma \alpha \delta​ γαδ可直接推导出 γ β δ ​ \gamma \beta \delta​ γβδ

对于P中的每个产生式 α → β ​ \alpha \to \beta​ αβ显然都有 α ⇒ β ​ \alpha \Rightarrow \beta​ αβ

若文法中存在一个直接推导序列,即 α 0 ⇒ α 1 ⇒ α 2 ⇒ … α n ( n > 0 ) ​ \alpha_0 \Rightarrow \alpha_1 \Rightarrow \alpha_2 \Rightarrow \dots \alpha_n (n > 0)​ α0α1α2αn(n>0)。则称 α 0 ​ \alpha_0​ α0推导 α n ​ \alpha_n​ αn α n ​ \alpha_n​ αn α 0 ​ \alpha_0​ α0的一个推导,记为 α 0 ⇒ + α n ​ \alpha_0 \Rightarrow^+ \alpha_n​ α0+αn。另外,用 α 0 ⇒ ∗ α n ​ \alpha_0 \Rightarrow^* \alpha_n​ α0αn表示 α 0 = α n ​ \alpha_0 = \alpha_n​ α0=αn

归约与直接规约

归约和直接归约即推导与直接推导的逆过程

若文法中有一个直接推导 α ⇒ β ​ \alpha \Rightarrow \beta​ αβ,则称 β ​ \beta​ β直接归约 α ​ \alpha​ α,或称 α ​ \alpha​ α β ​ \beta​ β的直接归约。

若文法中有一个推导 γ ⇒ ∗ δ \gamma \Rightarrow^* \delta γδ,则称 δ \delta δ归约 γ \gamma γ,或称 γ \gamma γ δ \delta δ的归约。

句型、句子

从开始符能推导出的符号串称为文法的句型,即 α \alpha α是文法的一个句型,当且仅当存在推导 S ⇒ ∗ α , α ∈ V ∗ S \Rightarrow^* \alpha, \alpha \in V^* Sα,αV

若X为文法的一个句型,且 X ∈ V T ∗ X \in V^*_T XVT,则称X是文法的一个句子,即仅含终结符的句型是一个句子

语言

从文法的开始符出发,能推导出的所有句子称为文法G产生的语言,记为 L ( G ) L(G) L(G)

若有文法 G 1 G_1 G1与文法 G 2 G_2 G2产生的语言相同 L ( G 1 ) = L ( G 2 ) L(G_1) = L(G_2) L(G1)=L(G2)),则称这两个文法等价

文法应用的一些例子

  1. G 1 = ( { S } , { a , b } , P , S ) ​ G_1 = ( \{S\}, \{ a, b\}, P, S )​ G1=({S},{a,b},P,S)

    其中,P为:

    • S → a S ​ S \to aS​ SaS
    • S → a S \to a Sa
    • S → b ​ S \to b​ Sb

    这是一种3型文法,其所能产生的语言分析如下:

    若选①号产生式,发现其是递归的,所以需要使用②、③产生式来作为出口终止递归,因此其可以产生的语言是 { a i ( a ∣ b ) ∣ i ≥ 1 } \{ a^i(a|b) | i \geq 1 \} {ai(ab)i1}(其中第一个|表示"或",后一个表示分离符,是i需满足的条件,下同);而仅选②、③产生式可以产生的语言是 { a ∣ b } \{ a|b \} {ab}

    因此 G 1 G_1 G1可以产生的语言: L ( G 1 ) = { a i ( a ∣ b )   ∣ i ≥ 1 } ⋃ { a ∣ b } = { a i ( a ∣ b )   ∣ i ≥ 0 } ​ L(G_1) = \{ a^i (a|b) \space | i \geq 1 \} \bigcup \{a|b \} = \{a^i (a|b) \space | i \geq 0 \}​ L(G1)={ai(ab) i1}{ab}={ai(ab) i0}

  2. G 2 = ( { S } , { a , b } , P , S ) G_2 = (\{S\}, \{a, b\}, P, S ) G2=({S},{a,b},P,S)

    其中,P为:

    • S → a S b ​ S \to aSb​ SaSb
    • S → a b S \to ab Sab

    这是一种2型文法,其所能产生的语言分析如下:

    若选①号产生式,发现其是递归的,需要用①号产生式作为出口。因此,①产生的语言为 { a n b n ∣ n ≥ 2 } \{ a^n b^n | n \geq 2 \} {anbnn2};若用②号产生式,则能产生的语言为 { a b } ​ \{ab\}​ {ab}

    不妨试试推导看看,假定我们用①号产生式递归两次后使用②号产生式,则推导展开如下 S ⇒ ① a S b ⇒ ① a a S b b ⇒ ② a a a b b b S \Rightarrow ①aSb \Rightarrow ①aaSbb \Rightarrow ②aaabbb SaSbaaSbbaaabbb。可以发现,产生的语言中a的个数与b的完全相同。其中的非终结符具有自嵌套特性,所以又称其实自嵌套的上下文无关文法。

    所以 G 2 G_2 G2可以产生的语言为: L ( G 2 ) = { a n b n ∣ n ≥ 1 } L(G_2) = \{ a^nb^n | n \geq 1 \} L(G2)={anbnn1}

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值