编译原理--语法分析:基础,LL

上下文无关文法的正式定义

一个上下文无关文法由终结符号,非终结符号,一个开始符号,一组产生式组成.
1.终结符号是组成串的基本符号.
2.非终结符号是表示串的集合的语法变量.
3.一个文法中,某个非终结符号被指定为开始符号.
这个符号表示的串集合就是这个文法生成的语言.
4.一个文法的产生式描述了将终结符号和非终结符号组合成串的方法.

符号表示约定

1.终结符号
a.字母表前面的小写字母
b.运算符号
c.标点符号
d.数字
e.黑体字符串
2.非终结符号
a.字母表中排在前面的大写字母
b.字母S
c.小写,斜体名字
3.其他
a.字母表后面的大写字母表示文法符号,即可能是终结符号,也可能是非终结符号
b.字母表后的小写字母,表示可能为空的终结符号串
c.小写希腊字母,表示可能为空的文法符号串.

推导

如果S=>^{*}α,其中S是文法G的开始符号,说α是G的一个句型.
一个句型可能既含终结符号,又含非终结符号,也可能是空串.
G的一个句子是不含非终结符号的句型.
可由文法生成的语言称为上下文无关语言.
1.最左推导
选择每个句型的最左非终结符号,进行推导.
2.最右推导
选择每个句型的最右非终结符号,进行推导

语法分析树和推导

基础:α_{1} = A的语法分析树是标号为A的单个结点
归纳步骤:设已经构造了一棵结果为α_{i-1}=X_{1}...X_{k}的语法分析树.
每个文法符号X_{i}可以是非终结符号,也可是终结符号.
设α_{i}是将α_{i-1}中的某个非终结符号X_{j}替换为β=Y_{1}...Y_{m}得到的句型.
为模拟此步骤,
在当前语法分析树中找出左起第j个非ε叶子结点.
这个结点标号为X_{j}.
向这个叶子结点添加m个子结点,从左边开始分别将这些子结点标号为
Y_{1},...,Y_{m}.
作为特殊情况,如m=0,则β=ε,给第j个叶子结点加上一个标号为ε的子结点.

二义性

如一个文法可为某个句子生成多棵语法分析树,它就是二义性的.

左递归的消除

立即左递归消除
设A->Aα_{1} | ... | Aα_{m} | β_{1} | ... | β_{n}
其中β_{i}都不以A开头.
替换为
A->β_{1}A' | ... | β_{n}A'
A'->α_{1}A' | ... | α_{m}A' | ε

消除左递归
输入:没有环或ε产生式的文法G
输出:等价的无左递归文法
算法:
按某顺序将非终结符号排序为A_{1}, ..., A_{n}
for(1到n的每个i)
{
	for(1到i-1的每个j)
	{
		将每个形如A_{i}->A_{j}γ的产生式替换为产生式组
		A_{i}->δ_{1}γ|...|δ_{k}γ,
		其中A_{j}->δ_{1}|...|δ_{k}是所有的A_{j}产生式
	}
	消除A_{i}产生式之间的立即左递归
}

递归下降的语法分析

void A()
{
	选择一个A产生式,A->X_{1}...X_{k};
	for(i = 1 to k)
	{
		if(X_{i}是一个非终结符号)
			X_{i}();
		else if(X_{i}等于当前输入符号a)
			读入下一输入符号;
		else /*发生一个错误*/;
	}
}
可以为上述过程加入回溯.这样允许按某个产生式展开失败时,可以继续尝试下一个

FIRST和FOLLOW

计算各个文法符号X的FIRST(X)时,不断应用如下规则,
直到没新的终结符号或ε可被加入到任何FIRST集合为止.
1.如X是一个终结符号,则FIRST(X)=X
2.如X->ε是一个产生式,将ε加入FIRST(X)
3.如有产生式X->Y_{1}...Y_{m},FIRST(Y_{1})加入X.
ε在FIRST(Y_{1})中时,继续将FIRST(Y_{2})加入X.以此类推.

计算所有非终结符号A的FOLLOW(A)集合时,不断应用如下规则,
直到再没新的终结符号可被加入任意FOLLOW集合为止.
1.$加入FOLLOW(S)
2.如有产生式A->αBβ,
则FIRST(β)中除ε外的所有符号都在FOLLOW(B).
FIRST(β)含ε,则FOLLOW(A)加入FOLLOW(B)
3.如有产生式A->αB,
则FOLLOW(A)加入FOLLOW(B).

LL(1)文法

不断对非终结符号依据下一终结符号进行无二义性展开的过程.

构造一个预测分析表
输入:文法G
输出:预测分析表M
方法:对文法G的每个产生式A->α,进行如下处理
1.对FIRST(α)中的每个终结符号a,将A->α加入M[A, a]
2.如ε在FIRST(α)中,则对FOLLOW(A)中的每个终结符号b,
将A->α加入M[A, b].
如ε在FIRST(α)中,且$在FOLLOW(A)中,
也将A->α加入M[A, $].

完成上述后,若M[A, a]没产生式,将其设为error.

非递归的预测分析

表驱动的预测语法分析
输入:一个串ω,文法G的预测分析表M
输出:如ω在L(G)中,输出ω的一个最左推导;否则,给出一个错误提示.
方法:最初,语法分析器格局如下:
输入缓冲区是ω$,G的开始符号S位于栈顶,下面是$.
设置ip使它指向ω的第一个符号,其中ip是输入指针
令X=栈顶符号
while(X != $)
{
	if(X等于ip所指向的符号a)
		执行栈的弹出操作,将ip向前移动一个位置
	else if(X是一个终结符号)
		error()
	else if(M[X, a]是一个报错条目)
		error()
	else if(M[X, a]=X->Y_{1}...Y_{k})
	{
		输出产生式X->Y_{1}...Y_{k}
		弹出栈顶符号
		将Y_{k}...Y_{1}压入栈中,Y_{1}位于栈顶
	}
	令X=栈顶符号
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实验2 文法的读入、判定和处理 一、实验目的 熟悉文法的结构,了解文法在计算机内的表示方法。 二、实验内容 1、 设计一个表示文法的数据结构; 2、 从文本文件中读入文法,利用定义的数据结构存放文法,并输出; 3、 本实验结果将来还有用。 三、实验要求 1、 了解文法定义的4个部分: G(Vn, Vt, S, P) Vn 文法终结符号集合,在实验中用大写的英文字母表示; Vt 文法终结符号集合,在实验中用小写的英文字母表示; S 开始符号,在实验中是Vn集合中的一个元素; P 产生,分左部和右部,左部为终结符号中的一个,右部终结符号或终结符号组成的字符串,如S->ab|c 2、 根据文法各个部分的性质,设计一个合理的数据结构用来表示文法, 1) 若使用C语言编写,则文法可以设计成结构体形,结构体中应包含上述的4部分, 2) 若使用C++语言或java语言编写,则文法可以设计成文法类形,类中至少含有4个数据成员,分别表示上述4个部分 文法数据结构的具体设计由学生根据自己想法完成,并使用C或C++语言或Java实现设计的数据结构。 3、 利用完成的数据结构完成以下功能: 1) 从文本文件中读入文法文法事先应写入文本文件); 2) 根据文法产生的结构,分析出文法的4个部分,分别写入定义好的文法数据结构的相应部分; 3) 整理文法的结构,判断该文法文法类型,是否为0型,1型,2型或3型文法,并输出判断结果; 4) 在计算机屏幕或者文本框中输出文法文法输出按照一个终结符号一行,开始符号引出的产生写在第一行,同一个终结符号的候选用“|”分隔的方输出。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值