编译原理实验——预测分析器详解及代码(1)

实验目的和要求

①理解无回溯的自上而下分析算法的构造思想。
②掌握LL(1)文法的判定方法。
③理解预测分析程序的构造过程。
④能够使用某种高级语言实现一个预测分析程序。

实验内容

编写一个预测分析程序,能实现以下功能:
①给定文法G,消除文法G的左递归和左公因子;
②构造并输出各非终结符的FIRST集和FOLLOW集;
③判定文法G是否为LL(1)文法;
④构造并输出G的预测分析表;
⑤任意输入一个输入串,可得到成功的分析或错误的提示,输出其分析过程或打印语法分析树。

实现思路

默认规则:
起始符S,其余大写字母为非终结符;
小写字母为终结符,#为ε;
产生式: A->BC, 其中这个是关于A的产生式,A为左部(左边部分),BC为右部 (右边部分)
Vt是终结符
Vn是非终结符

在这里插入图片描述

判断左递归类型

通过右产生式第一个字符的不断寻找,判断是否存在如E->E,T->T这种情况,如果存在则为间接左递归,没有则为直接左递归。
上代码:

//主要思想:递归,在一定次数内寻找E->E的情况,存在返回8
int judBD(int b,int step,char f,char z)
{
	int er;
	if(step==0)
		return 1;
    for(int i=b%m1;i<4*m1;i++)
    {
     	if(zg[i][0]==z)
		{
			for(int j=0;j<m2;j++)
			{
				if(zy[i][0]==fz[j][0]&&fz[j][0]!=z)
				{
//					printf("1111111111\n");
					z=fz[j][0];
					if(z==f)
						return 8;
					return judBD(++b,--step,f,z);
				}
			}	return judBD(++b,--step,f,z);
		}
    }
    return 0;
}

如题只有直接左递归,消除结果如下:
在这里插入图片描述

消除左递归

在这里插入图片描述

First集:

①简单推导

first,顾名思义就是该关于该符号的所有产生式右部第一个遇到终结符。

FOLLOW集

Follow集合是针对非终结符而言的,Follow(U)所表达的是句型中非终结符U所有可能的后随终结符号的集合,特别地,“#”是识别符号的后随符。注意Follow集合是从开始符号S开始推导。且follow集中不包含ε。

  1. follow(S)收入“#”,S为开始符号。

  2. 形如"A->…Ua…”的组合,把a直接收入到Follow(U)中。因a是紧跟在U后的终结符。

  3. 形如“A->…UP…”(P是非终结符)的组合,把First (P ) 直接收入到Follow(U)中
    特别,A->…UP,把follow(A)也收入follow(U)

  4. 形如"A->…U",即以U结尾,follow(A)收入follow(U)

Select集

在求出first集和follow集后

select(X->Y),先求first(Y),如果first(Y)存在#∈first(Y)的情况,则再求follow(X),最后求两者的并集即可即可
在这里插入图片描述

LL(1)文法的判断:

左部符号相同的进行交集比较,如果全部交集为空,则符合LL(1)文法:

Select(S->a)∩Select(S->^)∩Select(S->(T)) = {a}∩{^}∩{ ( } = ∅

Select(N->,SN)∩Select(N->#) ={ ) }∩{ , } =∅

都为空集,因此符合LL(1)文法

预测分析表:

直接select集按预测分析表格式输出,注意:如在根据输入串得到预测分析过程时,希望有T’->+,但是实际没有这个结果,此时考虑T’->ε。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

预测分析过程:

  • 首先将 和 开 始 符 E 压 栈 ( 字 符 序 列 后 需 要 加 上 和开始符E压栈(字符序列后需要加上 E),若输入的第一个字符为i,查看上面的表格,E和i对应的是E=>TE’,我们就把E出栈,把E’压栈,把T压栈(注意因为是左推导,左边的需要优先处理,所以左边的要最后压栈),重复上面的步骤,若匹配到终止字符,则将输入的字符序列的指针后移,直到匹配到最后的终止符号为止。
  • 在每次进栈,出栈过程中打印栈中元素。
    在这里插入图片描述

实验反思

1.在没有构思好大体结构时就下手,导致几次推翻重来
2.使用的结构太过基础,导致代码臃肿

实验代码

代码写的有点臃肿
https://blog.csdn.net/qq_41735944/article/details/106057197

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值