⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yufafenxi.cpp

📁 本程序可以对一个完整的类pascal程序进行语法分析并将分析的结果输出显示。 程序要求输入的字符串必须有完整的程序体说明以及程序开始的标志
💻 CPP
字号:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#define MAXBUF 255
int Cur=0;
int type[MAXBUF];//用来存放词法分析器生成的每个单词的种别号,语法分析器通过调用该数组中的值来判断是否符合文法定义。
int line[MAXBUF];//用来标记所处程序的行号方便查出错误位置。
int FuZhiYuJu();
int TiaoJianYuJu();
int XunHuanYuJu();
void BoolLiang();
void BiaoDaShi();
void Xiang();
void YinZi();
void YuJuChuan();
void YuJu();
void Body();
void ChengXu();
void Yacc();
int Judge(char*);
void lexscanf(FILE*,FILE*);
int Judge(char *p)   
{
	char *word[]={"if","then","else","while","do","begin","end","program"};
	int ptr,i,flag;
	flag=0;

    for(i=0;i<8;i++)
	{
		ptr=stricmp(p,word[i]);
		if(ptr==0)
		{
			flag=1;
			return(i+1);
		}
	}
	if(flag==0)
	{
		return 0;
	}
	return 0;
}
void lexscanf(FILE *fpin,FILE*fpout)
{
	char arr[MAXBUF];
	int i=0;
	int j=0;
	int lineo=1;
	char ch;
	while(1)
	{
		fscanf(fpin,"%c",&ch); //从输入文件中读入字符
		if(ch==' '||ch=='\t')  //清除空白
			;
		else if(ch=='\n')     //识别回车,行数+1
			lineo++;
		else if(isdigit(ch))  //如果输入字符为数字
		{
			while(isdigit(ch)) //一直读字符,直到读入的字符不是数字
			{
				arr[j]=ch;
				j++;
				fscanf(fpin,"%c",&ch);
			}
			arr[i] = 0;
			fseek(fpin,-1L,SEEK_CUR);
			char* temp1=(char*)malloc(j+1);
			memcpy(temp1,arr,j); //将缓冲区的内容拷贝到temp1中去
			temp1[j]='\0';
			j=0;
			fprintf(fpout,"%s\t\t%d\n",temp1,10); //在文件中写入数字
			type[Cur]=10;
			line[Cur]=lineo;
			Cur++;
			free(temp1);
		}
		else if(isalpha(ch))  //如果读入的字符为字母
		{
			while(isalpha(ch)||isdigit(ch))
			{
				arr[i]=ch;
				i++;
				fscanf(fpin,"%c",&ch);
			}
			arr[i] = 0;
			fseek(fpin,-1L,SEEK_CUR);
			char* temp=(char*)malloc(i+1);
			memcpy(temp,arr,i);
			temp[i]='\0';
			i=0;
			if(Judge(temp))  //如果读入的字母能与关键字相等
			{			
				fprintf(fpout,"%s\t\t%d\n",temp,Judge(temp)); //输出该关键字,并且输出类型号
				type[Cur]=Judge(temp);
				line[Cur]=lineo;
				Cur++;
			}
			else
			{
				fprintf(fpout,"%s\t\t%d\n",temp,9); //否则,认定为标示符
				type[Cur]=9;
				line[Cur]=lineo;
				Cur++;
			}
			free(temp);
		}
		else if(ch==':') //处理二字符运算符:=
		{
			fscanf(fpin,"%c",&ch);
			if(ch=='=')
			{
				fprintf(fpout,"%s\t\t%d\n",":=",11);
				type[Cur]=11;
				line[Cur]=lineo;
				Cur++;
			}
			else
				fprintf(fpout,"error in compiling line %d! Unknown character %c \n",lineo,ch);
		}
		else //处理各种单字符运算符
		{
			if(ch=='+')
			{
				fprintf(fpout,"%c\t\t%d\n",'+',12);
				type[Cur]=12;
				line[Cur]=lineo;
				Cur++;
				continue;
			}
			if(ch=='-')
			{
				fprintf(fpout,"%c\t\t%d\n",'-',13);
				type[Cur]=13;
				line[Cur]=lineo;
				Cur++;
				continue;
			}
			if(ch=='(')
			{
				fprintf(fpout,"%c\t\t%d\n",'(',14);
				type[Cur]=14;
				line[Cur]=lineo;
				Cur++;
				continue;
			}
			if(ch==')')
			{
				fprintf(fpout,"%c\t\t%d\n",')',15);
				type[Cur]=15;
				line[Cur]=lineo;
				Cur++;
				continue;
			}
			if(ch=='*')
			{
				fprintf(fpout,"%c\t\t%d\n",'*',16);
				type[Cur]=16;
				line[Cur]=lineo;
				Cur++;
				continue;
			}
			if(ch==';')
			{
				fprintf(fpout,"%c\t\t%d\n",';',17);
				type[Cur]=17;
				line[Cur]=lineo;
				Cur++;
				continue;
			}
			if(ch=='#') //终止符
			{
				fprintf(fpout,"%c\t\t%d\n",'#',18);
				type[Cur]=18;
				line[Cur]=lineo;
				Cur++;
				break;
			}
			else   //若都没找到,输入错误!
				fprintf(fpout,"error in compiling line %d! Unkonwn character %c \n",lineo,ch);
		}
	}
}
int FuZhiYuJu()  //赋值语句
{
	if(type[Cur]!=9)
	{
		printf("语法错误,缺少标示符。错误行号%d\n",line[Cur]);
	}
	Cur++;
	if(type[Cur]!=11)
	{
		printf("语法错误,缺少:=。错误行号%d\n",line[Cur]);
	}
	Cur++;
	BiaoDaShi();                         
	return 1;
}
int  TiaoJianYuJu() //条件语句
{
	if(type[Cur]!=1)
	{
		printf("语法错误,缺少if。错误行号%d\n",line[Cur]);
	}
	Cur++;
    BoolLiang();
	if(type[Cur]!=2)
	{
		printf("语法错误,缺少then。错误行号%d\n",line[Cur]);
	}
	Cur++;
	YuJu();
	if(type[Cur]!=3)
	{
		return 0;
	}
	Cur++;
	YuJu();
	return 1;
}
int XunHuanYuJu() //循环语句
{
	if(type[Cur]!=4)
	{
		printf("语法错误,缺少while。错误行号%d\n",line[Cur]);
	}
	Cur++;
	BoolLiang();
	if(type[Cur]!=5)
	{
		printf("语法错误,缺少do。错误行号%d\n",line[Cur]);
	}
	Cur++;
	YuJu();
	return 1;
}
void BoolLiang()  //布尔量
{
	if(type[Cur]!=9)
	{
		printf("语法错误,布尔量错误。错误行号%d\n",line[Cur]);		
	}
	Cur++;
}		
void BiaoDaShi()  //表达式
{
	Xiang();
	while(type[Cur]==12||type[Cur]==13)
	{
		Cur++;
		Xiang();
	}
}
void Xiang()  //项数
{
	YinZi();
	while(type[Cur]==16)
	{
		Cur++;
		YinZi();
	}
}
void YinZi()  //因子
{
	switch(type[Cur])
	{
		case 9:
			Cur++;
			break;
		case 10:
			Cur++;
			break;
		case 14:
			Cur++;
			BiaoDaShi();
			if(type[Cur]!=15)
			{
				printf("语法错误,缺少)。错误行号%d\n",line[Cur]);
			}
			Cur++;
			break;
		default:
			printf("语法错误,缺少因子。错误行号%d\n",line[Cur]);
	}
}
void YuJuChuan() //语句串
{
	YuJu();
	while(type[Cur]==17)
	{
		Cur++;
		YuJu();//每次遇到一个分号表示上一个语句判断完毕,进行下一个语句判断。
	}
}
void YuJu() //语句判断循环、分支、赋值语句的入口。
{
	
	switch(type[Cur])
	{
	case 9:
		if(FuZhiYuJu()==1)
		{
			printf("赋值语句\n");
		}
		break;
	case 1:
		if(TiaoJianYuJu()==0)
		{
			printf("if then 分支语句\n");
		}
		else
		{
			printf("if then else 分支语句\n");
		}
		break;
	case 4:
		if(XunHuanYuJu()==1)
		{
			printf("while do 循环语句,嵌套赋值语句\n");
		}
		break;
	case 7:
		return;
	default:
		printf("语法错误,缺少语句。错误行号%d\n",line[Cur]);
	}
}
void Body() //程序体用于识别程序主体开始
{
	switch(type[Cur])
	{
	case 6:
		break;
	default:
		printf("语法错误,缺少begin。错误行号%d\n",line[Cur]);
	}
	Cur++;

	if(type[Cur]!=7)
	{
		YuJuChuan();
	}
	switch(type[Cur])
	{
	case 7:
		break;
	default:
		printf("语法错误,缺少end。错误行号%d\n",line[Cur]);
	}
}
void ChengXu()  //程序用来识别程序段开始和结束字符
{
	switch(type[Cur])
	{
	case 8:
		break;
	default:
		printf("语法错误,缺少program。错误行号%d\n",line[Cur]);
	}
	Cur++;
	switch(type[Cur])
	{
	case 9:
		break;
	default:
		printf("语法错误,缺少标示符。错误行号%d\n",line[Cur]);
	}
	Cur++;
	switch(type[Cur])
	{
	case 17:
		break;
	default:
		printf("语法错误,缺少; 。错误行号%d\n",line[Cur]);
	}
	Cur++;
    Body();
	Cur++;
	switch (type[Cur])
	{
	case 18:			
		break;
	default:
		printf("语法错误,缺少# 。错误行号%d\n",line[Cur]);		
	}
	printf("语法分析完成!\n");
}
void Yacc()  //语法分析器
{
	Cur=0;
	ChengXu();
}
void main()
{
	FILE *fpin;
	FILE *fpout;
	if((fpin=fopen("d:\\lexin.txt","rt"))==NULL)
	{
		printf("Cannot open file!");
		exit(1);
	}
	if((fpout=fopen("d:\\lexout.txt","wt"))==NULL)
	{
		printf("Cannot open file!");
		exit(1);
	}
	lexscanf(fpin,fpout);
	Yacc();
	fclose(fpin);
	fclose(fpout);
	system("pause");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -