第一章 first集的计算

第一章 first集的计算

现在我们开始自己做的YACC部分,首先我们要计算first集。在计算first集之前,我们要了解关于文法的一些基础知识,理解这部分内容,可能会涉及到离散数学中的关系一章。显然,对关系运算的理解有助于对编译原理的理解。

1 基础知识

1.1 文法定义

参见编译原理教材,可知一个文法定义为一个四元组(VN, VT, P, S)其中VN为非终结符号(或语法实体,或变量)集;VT为终结符号集;P为产生式(也称规则)的集合;VN, VT和P是非空有穷集。S称做识别符号或开始符号,它是一个非终结符,至少要在一条规则中作为左部出现。

VN和VT不含公共元素,即VN∩VT = Φ。通常V表示VN∪VT,V称为文法G的字母表或字汇表。

定义1

如α→β是文法G=( VN, VT, P, S)的规则(或说是P中第一个产生式),γ和δ是V*中的任意符号,若有符号串v,w满足:v=γαδ,w=γβδ,则说v(应用规则α→β)直接产生w,或说w是v的直接推导。

定义2

如果存在直接推导的序列:v=w0=>w1=>w2…=>wn=w,(n>0),则称v推导出(产生)w(推导长度为n)。记做v=>+w。

定义3

若有v=>+w,或v=w,则记做v=>*w。

定义4

设G[S]是一文法,如果符号串x是从识别符号推导出来的,即有S=>*x,则称x是文法G[S]的句型。若x只由终结符号组成,则称x为G[S]的句子。

定义5

文法G所产生的语言定义为集合{x | S=>*x,其中S为文法的开始符号,且x∈VT *}。可用L(G)表示该集合。

定义6

若L(G1) = L(G2),则称文法G1和G2是等价的。

1.1.1 文法的类型

设G=(VN, VT, P, S);乔姆斯基把文法分为四种类型:

l 0型文法:也叫做短语文法。0型文法的能力相当于图灵机(Turing)。或者说,任何0型语言都是递归可枚举的;反之也成立。

对于G的每个产生式,α→β,是这样一种结构:α∈(VN∪VT)+,且至少含有一个非终结符,而β∈(VN∪VT)*

l 1型文法:也叫做上下文有关文法G的任何产生式α→β,均满足| α |≤ | β |,仅仅S→ε除外。这就意味着对非终结符的替换必须要考虑上下文,并且一般不准替换为空串。

l 2型文法:G的任何产生式为A→β,A∈VN,β∈(VN∪VT)*。也叫做上下文无关文法

l 3型文法:也叫做正规文法。G的任何产生式为A→αB或者A→α,其中,α∈VT*,A、B∈VN。上述叫做右线性文法,另有左线性,二者等价。(注:| α |表示串的长度)

1.1.2 First 集

好了,有这些语言和文法的概念,我们就开始讨论First集。如果上面的概念不太懂,可以直接跳过去。WACC代码中的语言(Language类)的定义与上面的定义类似,等会儿就可以在代码中看到。呵呵。

定义:(来自《编译原理及实践》 Kenneth C. Louden 著)

令X为一个文法符号(一个终结符或非终结符)或 ε,则集合First(X)由终结符组成,此外可能还有ε,它的定义如下:

若X是终结符或ε,则First(X)= {X} 。

若X是非终结符,则对于每个产生式X –>X1X2…Xn  ,First(X)都包含了First(X1)-{ε}。若对于某个i <  n,所有的集合First(X1)…..First(Xi )都包括了ε,则First(X)也包含了    First(Xi+1)-{ε},若First(X)也包含了ε

现在为任意串α= X1X2…Xn (终结符和非终结符组成的串)定义First(α),如下所示:First(α),如下所示,First(α)包含First(X1)-{ε}。对于每个i = 2,……n, 如果对于所有的k = 1,…..,i-1, First(Xk)包含了ε,则First(α)也包含了ε。

1.1.3 算法

根据该定义,我们可以得到符号First集如下算法,无论手算还是机算都适用。

1) 若X∈VT,则FIRST(X)={X};

2) 若X∈VN,且有产生式X→a…,则把a加入到FIRST(X)中;若X→ε也是一条产生式,则把ε也加到FIRST(X)中。

3) 若X→Y…是一个产生式且Y∈VN,则把FIRST(Y)中的所有非ε元素都加到FIRST(X)中;若X→Y1Y2…Yk是产生式,Y1,…,Yi-1都是非终结符,而且对于任何的j,1≤j≤i-1,FIRST(Yj)都含有ε,则把FIRST(Yi)中的所有非ε元素都放到FIRST(X)中;特别的是,若所有的FIRST(Yj)均含有ε,j=1,2,…,k,则把ε加到FIRST(X)中

4) 重复上面的过程直到每个First集不再增大。

也许有人会疑问,要是First集无限增大怎么办?循环不就结束不了?其实大可放心,First集也好,包括后面的epsilon 闭包等,都是一种关系,可以用有序对<X,a>来表示,有限个元素产生的关系是有限的,你可以参考离散数学的教材就可以知道,其实你不懂离散数学,使用高中学的组合也可以知道这个结论。呵呵。

1.1.4 手算例子

给定文法

stmt_sequence->stmt stmt_seq 

stmt_seq->; stmt_sequence 

stmt_seq->

stmt->s 

在文法中,我们不再给定哪些符号是终结符,哪些是非终结符。我们在这里认为,凡是在右部出现而没在左部出现的符号均为终结符,其它均为非终结符。在其它编译原理的教材中,右部为空使用A->ε表示右部为空,但我们在这里不采用这种表示方法。如stmt_seq-> 就表示stmt_seq右部为空。

文法first集计算

规则

第一遍

第二遍

stmt_sequence->stmt stmt_seq

First(stmt_sequence)={s}

stmt_seq->; stmt_sequence 

First(stmt_seq)={;}

stmt_seq->

First(stmt_seq)={;ε}

stmt->s 

First(stmt)={s}

图表 21

所以得出

First(stmt_sequence) = {s}

First(stmt_seq)={;ε}

First(stmt)={s}

First(s) = {s}

First(;) = {;}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值