程序设计语言编译原理(二)

c词法分析的任务是:从左至右的逐个字符地对源程序进行扫描,产生的一个个单词符号,把作为字符串的源程序改造成为单词符号串的中间程序。

程序语言的单词符号可以分为下列五种:关键字,标志符,常数,运算符,界符。

词法分析的重点是使用状态转化图,一个程序语言的所有单词符号的识别可以使用状态转化图。

正则表达式和有限自动机:

正规式和正规集

对于字母表A,我们所感兴趣的是它的一些特殊的子集,叫做正规集。正规集合正规式的递归定义如下:

(1)e和fi都是A上的正规式,他们所表示的集合的正规集为|e|和|fi|

(2)任何a属于A,a是字母集A上的一个正规式,它表示的正规集为|a|

(3)假定U和V都是A上的正规式,它们所表示的正规集分别记为L(U)和L(V)那么(U|V)、(U·V)、(U)*都是正规集。

e.g. 令A = {a,b},下面是A上的正规式和正规集

e.g.正规式                                     正规集

ba*                                       A上所有以b为首,后跟任意多的a字

a(a|b)*                            A上所有以a为首的字

(a|b)*aa|bb(a|b)*           A上的所有包含连续两个a或者连续两个b的字

若两个正规式表示的正规集相同,可以认为两个正规式是等价的。

对于正规表达式,有下面这些定律成立:

(1)U|V = V|U

(2)U|(V|W)= (U|V)|W

(3)U(VW)= (UV)W

(4)U(V|W)= UV|UW

(5)eU = Ue = U

确定有限自动机

一个确定有限自动机(DFA)M是一个五元式,M = (S,A, m,S0,F)其中

(1)S是一个有限集,它的每个元素称为一个状态。

(2)A是一个有穷字母表,它的每个元素为一个输入字符。

(3)m是一个单值映射,d(s,a)=t 意味着:当现在的状态为s,输入字符为a时,将转换到下一个状态t。我们称t为s的后继状态。

(4)S0 是唯一的初态

(5)F是一个可空的终态集。

正规文法与有限自动机的等价性

对于正规文法G和有限自动机M,如果有L(G)= L(M),则称G和M是等价的。关于正规文法和有限自动机的等价性,有以下的结论。

(1)对每一个右线性正规文法或左线性正规文法G,都存在一个有限自动机(FA)M, 使得L(M)=L(G)。

(2)对每一个FAM,都存在一个右线性文法Gr和Gl,使得L(M)=L(Gr)=L(Gl)

语法分析——自上而下分析

自上而下的分析就是从文法的开始符号出发,向下推导,推出句子。这种方法是带回溯的,对于任何输入串,试图用一切可能的办法,从文法开始符号出发,自上而下地为输入串建立一个语法树。这种方法存在很多缺陷:

首先是文法的做递归性问题。一个文法是含有左递归的,如果存在非终结符P=>Pa,含有左递归的文法将使上述的自上而下的分析过程陷入无限循环。

其次,由于回溯,就碰到一大堆麻烦的事情。如果我们走错道路,就要花大力气回头。

第三,在上述的自上而下分析过程中,当一个非终结符用某一候选匹配成功时,这种成功可能是暂时的。

第四,当最终报告分析不成功时,我们难于知道输入串中出错的确切位置。

最后,由于带回溯的自上而下分析实际上采用了一种穷尽一切可能的试探法,因此不可避免的具有严重的效率问题。

 LL(1)分析法

由于自上向下的分析方法不允许文法含有任何左递归,为了构造不带回溯条件的自上向下分析算法,首先要好消除文法的左递归性,并找出客服回溯的充分必要条件。

左递归的消除

直接消除产生式中的左递归是比较容易的。假定关于非终结符P的规则为P->Pa|b 其中,b不以P开头。那么,我们可以把P的规则改写成为如下的非直接左递归形式:

P->bP'

P'->aP'|e(e为空字)

这种形式和原来的形式是等价的,也就是说,从P的倒出符号串是相同的。一般的做法都是把直接的左递式消除成为直接右递归。如何消除一个文法的直接左递归呢?

消除左递归算法:

(1)把文法G的所有非终结符按任一种顺序排列成P1,P2,Pn;按此顺序执行。

(2)FOR i=1 To n Do

 BEGIN

    FOR j=1 To i-1 Do

把形如P->Pj R的规则改写成

Pi->D1R|D2R|D3R|……|D4R。其中Pj->D1|D2|D3……Dn是关于D的所有规则。

消除关于P1规则的直接左递归性

END

例.  考虑文法

S->Qc|c

Q->Rb|b

R->Sa|a

虽然不具有直接左递归,但是S、Q、R都是左递归的。

令其非终结符的排序为R、Q、S。对于R,不存在直接左递归。把R代入到Q的有关候选后,我们把Q的规则变为:

Q->Sab|ab|b

现在的Q同样不含直接左递归,把它代入到S的有关候选之后,S变成

S->Sabc|abc|bc|c

经消除了S的直接左递归后,我们得到了整个文法为:

S->abcS'|bcS'|cS'

S'->abcS'|e

注意由于采用的非终结符排序不同,最后得到的文法在形式上可能不一样。但是不难证明他们都是等价的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1解:源程序是指以某种程序设计语言所编写的程序。目标程序是指编译程序(或解释程序)将源程序处理加工而得的另一种语言(目标语言)的程序。翻译程序是将某种语言翻译成另一种语言程序的统称。编译程序与解释程序均为翻译程序,但者工作方法不同。解释程序的特点是并不先将高级语言程序全部翻译成机器代码,而是每读入一条高级语言程序语句,就用解释程序将其翻译成一段机器指令并执行之,然后再读入下一条语句继续进行解释、执行,如此反复。即边解释边执行,翻译所得的指令序列并不保存。编译程序的特点是先将高级语言程序翻译成机器语言程序,将其保存到指定的空间中,在用户需要时再执行之。即先翻译、后执行。 2解:一般说来,编译程序主要由词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、代码优化程序、目标代码生成程序、信息表管理程序、错误检查处理程序组成。 3解:C语言的关键字有:auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while。上述关键字在C语言中均为保留字。 4解:C语言中括号有三种:{},[],()。其中,{}用于语句括号;[]用于数组;()用于函数(定义与调用)及表达式运算(改变运算顺序)。C语言中无END关键字。逗号在C语言中被视为分隔符和运算符,作为优先级最低的运算符,运算结果为逗号表达式最右侧子表达式的值(如:(a,b,c,d)的值为d)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值