编译原理递归下降语法分析器

a.选择测试代码,begin a:=9;x:=2*3;b:=a+xend#,即词法分析器的输入,所示。
b.统计测试程序包含的单词符号,假定关键字、界符、运算符都是一符一种,设计单词符号对应的种别码,如表1
单词符号种别码
c.词法分析得到的种别码串为1,10,18,11,26,10,18,11,15,11,26,10,18,10,13,10,6,0,此为语法分析的输入。

源程序:

//递归下降语法分析程序
#include<stdio.h>
#include<stdlib.h>
//#define debug


//定义全局变量
char *str;				//词法分析所得的单词符号串
int p_token=0;			//字符串指针
int syn;				//种别码数值(十进制)
int kk = 0;				//错误标志


//函数声明
int scaner();			//读取下一单词(种别码)
void lrparse();			//递归下降分析函数
void statements();		//语句串分析函数
void statement();		//语句分析函数
void expression();		//表达式分析函数
void term();			//项分析函数
void factor();			//因子分析函数



int main()
{
	FILE *p;					//词法分析器输出的单词符号串的文件指针
	int filesize;				//单词符号串长度
	char *fname = "a.txt";		//单词符号串所在的文件
	
	//打开单词符号串所在的文件
    p = fopen(fname,"rb");		//p = fopen("D:\\a.txt","rb");
	if(p == NULL)
	{
		printf("打开文件%s错误\n",fname);
		exit(1);//exit(-1);
	}

	fseek(p,0,SEEK_END);		//指向文件末尾
	filesize = ftell(p);		//获取文件长度
	str = (char*)malloc(filesize+1);//动态内存分配
	rewind(p);
	fread(str,sizeof(char),filesize,p);
	str[filesize] = '\0';		//字符串结束标志
	fclose(p);
	//输出文件中的代码
	printf("a.txt文件中的单词符号串为:\n");
	puts(str);

	
#ifdef debug
	printf("\n%d\n",scaner());
	printf("%d\n",scaner());
	printf("%d\n",scaner());
	printf("%d\n",scaner());
	printf("%d\n",scaner());
#endif
	lrparse();

	return 0;
}




/* *****************************************/
/*                函数定义                 */
/* *****************************************/
int scaner()
{
	char syns[7];			//种别码字符串
	int i = 0;				//数组下标
	char ch = str[p_token++];//等价于char ch = str[p_token];p_token++;
	//去除空格
	while(' '==ch || '\r'==ch || '\n'==ch || '\t'==ch)  //文件回车='\r\n',windows
	{
		ch = str[p_token++];
	}
	syns[i++] = ch;        //空格后的第一个非空格字符
	ch = str[p_token++];
	while(' '!=ch && '\r'!=ch && '\n'!=ch && '\t'!=ch && '\0'!=ch)  //'\0'!=ch,单词符号串结束标志
	{
		syns[i++] = ch;
		ch = str[p_token++];		
	}
	//printf("%d\n",atoi(syns));
	return atoi(syns);
}


//递归下降分析函数
void lrparse()
{
	syn = scaner();
	if(syn == 1)				//begin
	{
		syn = scaner();
		statements();
		if (syn == 6)			//end
		{
			syn = scaner();
			if(syn==0 && kk==0)	//#
				printf("success\n");
		}
		else  //缺end
		{
			if(kk != 1)
			{
				printf("缺end错误\n");
				kk = 1;
			}
		}
	}
	else
	{
		printf("begin错误\n");
		kk = 1;
	}
}

//语句串分析函数
void statements()
{
	statement();
	while(syn == 26)		//分号;
	{
		syn = scaner();
		statement();
	}
}

//语句分析函数
void statement()
{
	if(syn == 10)			//标识符
	{
		syn = scaner();
		if(syn == 18)		//:=
		{
			syn = scaner();
			expression();
		}
		else
		{
			printf("赋值号错误\n");
			kk = 1;
		}
	}
	else
	{
		printf("语句错误\n");
		kk = 1;
	}
}

//表达式分析函数
void expression()
{
	term();
	while(syn==13 || syn==14)		//+或-
	{
		syn = scaner();
		term();
	}
}

//项分析函数
void term()
{
	factor();
	while(syn==15 || syn==16)		//*或/
	{
		syn = scaner();
		factor();
	}
}

//因子分析函数
void factor()
{
	if(syn==10 || syn==11)			//标识符或常数
		syn = scaner();
	else if(syn == 27)				//(
	{
		syn = scaner();
		expression();
		if(syn == 28)
			syn = scaner();
		else
		{
			printf(")错误\n");
			kk = 1;
		}
	}
	else
	{
		printf("表达式错误\n");
		kk = 1;
	}
}

运行结果:
在这里插入图片描述

发布了11 篇原创文章 · 获赞 7 · 访问量 1695

猜你喜欢

转载自blog.csdn.net/qq_43015237/article/details/103079079
今日推荐