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

📄 语法分析程序.txt

📁 该语言的语法在《编译原理与实践》第九章附录中有详细的介绍
💻 TXT
字号:
/*************************************************************************
 *                           语法分析1:递归子程序法
 *
 * 问题描述:设定好自己的文法
 *           从控制台读取文件,运用以上文法进行语法分析。
 *           将分析结果显示在屏幕上并存入另一文件中。
 *
 * 说明:1、采用功能独立的小函数段实现。
 *       2、使用递归子程序法。
 *       3、内码对照表见《编译方法》(马知行,曹启君编)P167。
 *       4、本程序实现过程未参照上述书上。
 *       5、本程序在原有词法分析程序基础上修改而成。
 *       6、所读取文件和存储文件在本工程所在目录下。
 *       7、定义文法:(读取文件以"#"结尾)
 *          (1)主函数:S()
 *          void main()
 *          {
 *             整型定义;
 *             整型定义;
 *             for循环;
 *             if判断;
 *             return;
 *          }
 *          (2)整型定义或赋值(a为任一标示符):A()
 *          int a=2;
 *          或:
 *          a=3;
 *          (3)for循环:B()
 *          for(i=0;i<3;i++)(i为任一标示符)
 *          {
 *             整型赋值;
 *          }
 *          (4)if判断:C()
 *          if(a=0)
 *          {
 *             整型赋值;
 *          }
 *
 ************************************************************************/
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<process.h>
#include<iostream.h>
#define LENKEY 15 
#define LENSIGN 17  
#define WRITEFILE "D:\\write.txt"

struct{
	char name[31];  
	int addr;
}word[1000];                        //word[1000]: 存储已分析单词的名称和内码
char *keyword[LENKEY] = {"program","const","var","integer","long","procedure","if","then","while","do","read","write","begin","end","odd"};
char *sign[LENSIGN] = {"+","-","*","/","=","<>","<","<=",">",">=",".",",",";",":",":=","(",")"};
FILE *f,*fw;
int totalwords = 0;                 //totalwords: 当前已分析单词的数量
int next=0;                         //next: 当前的单词序号
char w[20];

void SaveWords(int,char *[]);       //SaveWords(): 将文件中的单词存入word[]中
void get_w();                       //get_w(): 读取一个单词
void S();                           //S(): 分析main()函数
void A();                           //A(): 分析整型定义和赋值
void B();                           //B(): 分析for循环
void C();                           //C(): 分析if判断

void OpenFile(char *,char *);       //OpenFile(): 打开文件
void ReadLine(FILE *,char []);      //ReadLine(): 读取文件中一行
void DealLine(char []);             //DealLine(): 处理一行
bool Analyse(char []);              //Analyse(): 分析一个单词
bool AnalyseSign(char []);          //AnalyseSign(): 分析一个符号单词
bool AnalyseAlpha(char a[]);        //AnalyseAlpha(): 分析一个关键字或标示符单词
bool AnalyseNum(char n[]);          //AnalyseNum(): 分析一个整数单词
void DealError(char []);            //DealError(): 处理错误信息
void DealResult(FILE *);            //DealResult(): 输出结果,并将结果写入文件

/*************************************************************************
 * 主函数
 ************************************************************************/
void main(int argc,char *argv[])
{
	SaveWords(argc,argv);
	//语法分析
	get_w();
	S();
	get_w();
	if(strcmp(w,"#")!=0)
	{
		cout<<""<<endl;
		fprintf(fw,"Error!");
	}
	return;
	fclose(fw);
}
/*************************************************************************
 * 函数名称:
 *   get_w()
 * 参数:
 *   无。
 * 返回值:
 *   空。
 * 功能:
 *   从word[]中读取一个单词。
 ************************************************************************/
void get_w()
{
	strcpy(w,word[next].name);
	next++;
}
/*************************************************************************
 * 函数名称:
 *   S()
 * 参数:
 *   无。
 * 返回值:
 *   空。
 * 功能:
 *   分析主函数。
 ************************************************************************/
void S()
{
	if(strcmp(w,"void")==0)
	{
		get_w();
		if(strcmp(w,"main")==0)
		{
			get_w();
			if(strcmp(w,"(")==0)
			{
				get_w();
				if(strcmp(w,")")==0)
				{
					get_w();
					if(strcmp(w,"{")==0)
					{
						get_w();
						A();              //定义整型变量
						get_w();
						A();              //定义整型变量
						get_w();
						B();              //判断for循环
						get_w();
						C();              //判断if判断
						get_w();
						if(strcmp(w,"return")==0)
						{
							get_w();
							if(strcmp(w,";")==0)
							{
								get_w();
								if(strcmp(w,"}")==0)
								{
									cout<<"符合所定义语法"<<endl;
									fprintf(fw,"符合所定义语法");
									return;
								}
							}
						}

					}
				}
			}
		}

	}
	cout<<"不符合所定义语法"<<endl;
	fprintf(fw,"不符合所定义语法");
	return;
}
/*************************************************************************
 * 函数名称:
 *   A()
 * 参数:
 *   无。
 * 返回值:
 *   空。
 * 功能:
 *   分析整型定义或赋值。
 ************************************************************************/
void A()
{
	if(strcmp(w,"int")==0)
	{
		get_w();
		if(word[next-1].addr==34)
		{
			get_w();
			if(strcmp(w,"=")==0)
			{
				get_w();
				if(word[next-1].addr==33)
				{
					get_w();
					if(strcmp(w,";")==0)
						return;
				}
			}
		}
	}
	else if(word[next-1].addr==34)
	{
		get_w();
		if(strcmp(w,"=")==0)
		{
			get_w();
			if(word[next-1].addr==33)
			{
				get_w();
				if(strcmp(w,";")==0)
					return;
			}
		}
	}
	cout<<"A不符合整型定义"<<endl;
	fprintf(fw,"A不符合整型定义");
	return;

}
/*************************************************************************
 * 函数名称:
 *   B()
 * 参数:
 *   无。
 * 返回值:
 *   空。
 * 功能:
 *   分析for循环。
 ************************************************************************/
void B()
{
	if(strcmp(w,"for")==0)
	{
		get_w();
		if(strcmp(w,"(")==0)
		{
			get_w();
			A();  //i=0
			get_w();
			if(word[next-1].addr==34)
			{
				get_w();
				if(strcmp(w,"<")==0)
				{
					get_w();
					if(word[next-1].addr==33)
					{
						get_w();
						if(strcmp(w,";")==0)
						{
							get_w();
							if(word[next-1].addr==34)
							{
								get_w();
								if(strcmp(w,"+")==0)
								{
									get_w();
									if(strcmp(w,"+")==0)
									{
										get_w();
										if(strcmp(w,")")==0)
										{											
											get_w();
											if(strcmp(w,"{")==0)
											{
												get_w();
												A();
												get_w();
												if(strcmp(w,"}")==0)
												{					
													return;
												}
											}
										}
									}
								}

							}
						}
					}
				}
			}
		}
	}
	cout<<"B不符合for循环定义"<<endl;
	fprintf(fw,"B不符合for循环定义");
}
/*************************************************************************
 * 函数名称:
 *   C()
 * 参数:
 *   无。
 * 返回值:
 *   空。
 * 功能:
 *   判断if语句。
 ************************************************************************/
void C()//if判断
{
	if(strcmp(w,"if")==0)
	{
		get_w();
		if(strcmp(w,"(")==0)
		{
			get_w();
			if(word[next-1].addr==34)
			{
				get_w();
				if(strcmp(w,"=")==0)
				{
					get_w();
					if(strcmp(w,"=")==0)
					{
						get_w();
						if(word[next-1].addr==33)
						{
							get_w();
							if(strcmp(w,")")==0)
							{
								get_w();
								if(strcmp(w,"{")==0)
								{
									get_w();
									A();
									get_w();
									if(strcmp(w,"}")==0)
									{					
										return;
									}
								}
							}
						}
					}
				}
			}
		}
	}
	cout<<"C不符合if循环定义"<<endl;
	fprintf(fw,"C不符合if循环定义");
}
/*************************************************************************
 * 函数名称:
 *   SaveWords()
 * 参数:
 *   int argc2         - 控制台输入的参数个数;
 *   char *argv2[]     - 控制台输入的参数。
 * 返回值:
 *   空。
 * 功能:
 *   将文件中读取的单词存入word[]中。
 ************************************************************************/
void SaveWords(int argc2,char *argv2[])
{
	FILE *fread,*fwrite;
	char line[200];
    //打开文件
	OpenFile(argv2[2],"w");
	fw=f;
	OpenFile(argv2[1],"r");
	fread=f;
	if(argc2<3)OpenFile(WRITEFILE,"w");
	else OpenFile(argv2[2],"w");
	fwrite=f;
	//读取一行,处理一行
	while(!feof(fread))
	{
		ReadLine(fread,line);
		DealLine(line);
	}
	//关闭文件
	fclose(fread);
	fclose(fwrite);
}
/*************************************************************************
 * 函数名称:
 *   OpenFile()
 * 参数:
 *   char *route       - 文件所在路径;
 *   char *manner      - 文件打开方式。
 * 返回值:
 *   空。
 * 功能:
 *   打开文件。
 ************************************************************************/
void OpenFile(char *route,char *manner)
{
	if((f = fopen(route,manner))==NULL)
	{
		printf("connot open the file\n");
		exit(0);
	}
}
/*************************************************************************
 * 函数名称:
 *   ReadLine()
 * 参数:
 *   FILE *f           - 所要读取的文件;
 *   char line[]       - 读到的一行。
 * 返回值:
 *   空。
 * 功能:
 *   读取文件中的一行。
 ************************************************************************/
void ReadLine(FILE *f,char line[])
{
	if(feof(f))return;
	int i=0;
	char ch = fgetc(f);
	while(ch!='\n'&&!feof(f))
	{
		line[i]=ch;
		i++;
		ch = fgetc(f);
	}
	line[i] = '\0';
	return;
}
/*************************************************************************
 * 函数名称:
 *   DealLine()
 * 参数:
 *   char line[]       - 已读取的文件中的一行。
 * 返回值:
 *   空。
 * 功能:
 *   处理已读取的文件中的一行。
 ************************************************************************/
void DealLine(char line[])
{
	int i=0,n=0;
	char str[30];
	while(line[i]!='\0')
	{
		//略去空格
		while(isspace(line[i]))
			i++;
		//关键字、标示符、无符号整数(字母、数字、下划线的组合)
		while((line[i]!='\0')&&(isalnum(line[i])||isalpha(line[i])||line[i]=='_'))
		{
			str[n]=line[i];
			n++;
			i++;
		}
		if(n>0)
		{
			str[n]='\0';
			if(!Analyse(str))
			{
				i=i-strlen(str);
				str[0]=line[i];
				str[1]='\0';
				i++;
				Analyse(str);
			}
			n=0;
		}
		//符号、错误词法
		while((line[i]!='\0')&&(!isalnum(line[i]))&&(!isalpha(line[i]))&&(line[i]!='_'))
		{
			while(isspace(line[i]))
				i++;
			if((line[i]!='\0')&&((isalnum(line[i]))||(isalpha(line[i]))||(line[i]=='_')))break;
			str[n]=line[i];
			n++;
			i++;
		}
		if(n>0)
		{
			str[n]='\0';
			if(!Analyse(str))
			{
				i=i-strlen(str);
				str[0]=line[i];
				str[1]='\0';
				i++;
				Analyse(str);
			}
			n=0;
		}
	}
	return;	
}
/*************************************************************************
 * 函数名称:
 *   Analyse()
 * 参数:
 *   char str[]        - 在一行中提取的一个单词。
 * 返回值:
 *   true              - 处理无异常。
 *   false             - 该单词包含相邻的字符,需退出重新划分单词。
 * 功能:
 *   分析一个单词。
 ************************************************************************/
bool Analyse(char str[])
{
	int n=0,i=0,num=0;
	//以字母或下划线开头
	if((isalpha(str[0]))||(str[0]=='_'))
		AnalyseAlpha(str);
	//以数字开头
	else if(isalnum(str[0]))
	{
		if(!AnalyseNum(str))
			DealError(str);
	}
	//其它情况
	else
	{
		//多个符号相邻的情况
		if((strlen(str)>1)&&(strcmp(str,"<>")!=0)&&(strcmp(str,"<=")!=0)&&(strcmp(str,">=")!=0)&&(strcmp(str,":=")!=0))
			return false;
		if(!AnalyseSign(str))
			DealError(str);
	}
	return true;
}
/*************************************************************************
 * 函数名称:
 *   AnalyseAlpha()
 * 参数:
 *   char a[]          - 待分析的字母和数字组合单词。
 * 返回值:
 *   true              - 属于内部码中的单词。
 * 功能:
 *   分析一个单词是否是关键字或标示符。
 ************************************************************************/
bool AnalyseAlpha(char a[])
{
	int i=0;
	for(i=0;i<LENKEY;i++)
	{
		if(!strcmp(a,keyword[i]))
		{
			strcpy(word[totalwords].name,keyword[i]);
			word[totalwords].addr = i+1;
			totalwords++;
			return true;
		}
	}
	strcpy(word[totalwords].name,a);
	word[totalwords].addr = 34;
	totalwords++;
	return true;
}
/*************************************************************************
 * 函数名称:
 *   AnalyseNum()
 * 参数:
 *   char n[]          - 待分析的符号单词。
 * 返回值:
 *   true              - 属于内部码中的单词。
 *   false             - 不属于内部码中的无符号整数。
 * 功能:
 *   分析一个单词是否是内部码中的无符号整数。
 ************************************************************************/
bool AnalyseNum(char n[])
{
	int i=0;
	for(i=0;i<(int)strlen(n);i++)
		if(n[i]<'0'||n[i]>'9')
			return false;
	strcpy(word[totalwords].name,n);
	word[totalwords].addr = 33;
	totalwords++;
	return true;
}
/*************************************************************************
 * 函数名称:
 *   AnalyseSign()
 * 参数:
 *   char s[]          - 待分析的符号单词。
 * 返回值:
 *   true              - 属于内部码中的单词。
 *   false             - 不属于内部码中的符号单词。
 * 功能:
 *   分析一个单词是否是内部码中的符号单词。
 ************************************************************************/
bool AnalyseSign(char s[])
{
	int i=0;
	for(i=0;i<LENSIGN;i++)
	{
		if(!strcmp(s,sign[i]))
		{
			strcpy(word[totalwords].name,s);
			word[totalwords].addr = i+16;
			totalwords++;
			return true;
		}
	}
	if(!strcmp(s,"#"))
	{
		strcpy(word[totalwords].name,s);
		word[totalwords].addr = 35;
		totalwords++;
		return true;
	}
	return false;
}
/*************************************************************************
 * 函数名称:
 *   DealError()
 * 参数:
 *   char str[]        - 错误的单词。
 * 返回值:
 *   空。
 * 功能:
 *   处理错误单词。
 ************************************************************************/
void DealError(char str[])
{
	strcpy(word[totalwords].name,str);
	word[totalwords].addr = 36;
	totalwords++;
	return;
}

⌨️ 快捷键说明

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