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

📄 yufa.cpp

📁 编译原理课程设计
💻 CPP
字号:
#include<stdio.h>
#include<string.h>
#include<stdlib.h> 
#include<ctype.h>
#include<iostream.h>
#include<windows.h>

/*关键字*/
typedef struct keyword
{
	char *name;
    int code;
}keyword;

keyword key[11]={{"begin",1},{"end",2},{"if",3},{"then",4},{"else",5},
{"for",6},{"do",7},{"while",8},{"and",9},{"or",10},{"not",11}};

#define ID 12
#define INT 13
#define ADD 14
#define MIN 15
#define MUL 16
#define DIV 17
#define LT 18
#define LE 19
#define EQ 20
#define GE 21
#define GT 22
#define NE 23
#define EVA 24
#define LP 25
#define RP 26
#define SEM 27

/*相关初始化*/
FILE *in,*outfile;//输入输出文件指针
char token[50];//存储一个单词词文中的各个字符
int error_count=0;//错误计数
int b;//记录数值大小
int k;//记录标识符长度
char ch1;//辅助变量
int row=0;//代码行数
int queue=0;//代码列数

/*报错函数*/
void report_error(int a)
{
	error_count++;
	switch(a)
	{
	case 1:cout<<"标识符长度超过6,不合法"<<"   "<<"行"<<row<<","<<"列"<<queue<<endl;
		break;
	case 2:cout<<"非法字符"<<"   "<<"行"<<row<<","<<"列"<<queue<<endl;
		break;
	case 3:cout<<"数值超过最大表示范围,溢出"<<"   "<<"行"<<row<<","<<"列"<<queue<<endl;
		break;
	case 4:cout<<"没有匹配的注释符 '*/' "<<"   "<<"行"<<row<<","<<"列"<<queue<<endl;
		break;
	case 5:cout<<"标识符以数字开头,不合法"<<"   "<<"行"<<row<<","<<"列"<<queue<<endl;
		break;
	}
}

/*输出函数*/
void out(char *t,int s)
{	
	cout<<"("<<t<<" , "<<s<<")"<<"   "<<"行"<<row<<","<<"列"<<queue<<endl;
	/*输入到文件里*/
	outfile =fopen("finish.txt","ar");
	fprintf(outfile,"(%s,%d)\n",t,s);
	fclose(outfile);
}

/*查找关键字*/
int lookup(char *c)
{	
    int h=1;//标记是否为关键字,1为不是,0为是
	for(int i=0;i<11;i++)//比较关键字
	{
		if((h=strcmp(c,key[i].name))==0)
			break;
	}		
	if(h) 
		return -1;
	else
		return i;
	
}

/*词法分析主函数*/
void scanner()
{
	/*函数初始化*/
	char ch;
	int i=0,c;	
	while((ch=fgetc(in))!=EOF)//判断代码是否结束
	{   
		if(isalpha(ch))//判断是否为字符开头
		{
			token[0]=ch;
			ch=fgetc(in);
			i=1;
			while(isalnum(ch))//判断是否为字符或数字
			{
				token[i]=ch;
				i++;
				ch=fgetc(in);
			}
			token[i]='\0';
			fseek(in,-1,1);//移动文件指针
			c=lookup(token);//判断是否为关键字
			if(c==-1)	   
			{
				if((k=strlen(token))<7)//判断是否超过标识符号的最大长度
					out(token,ID);			
				else 
					report_error(1);	
			}
			else
				out(key[c].name,key[c].code);		
		}		
		else
		{
			if(isdigit(ch))//判断是否为数字开头
			{
				token[0]=ch;
				ch=fgetc(in);
				i=1;
				while(isdigit(ch))//判断是否为数字
				{
					token[i]=ch;
					i++;
					ch=fgetc(in);
				}				
				if(isalpha(ch))//判断是否为字符
				{
					token[i]=ch;
					i++;
					ch=fgetc(in);
					while(isalnum(ch))
					{
						token[i]=ch;
						i++;
						ch=fgetc(in);
					}
					token[i]='\0';
					fseek(in,-1,1);
					report_error(5);		
				}
				else
				{					
					token[i]='\0';
					fseek(in,-1,1);
					b=atoi(token);
					if((b<=65535)&&(b>=0))//判断是否超过数值最大表示范围
						out(token,INT);					
					else 
					{
						if(b>65535)
							report_error(3);
					}
				}                
			}
			else
			{
				switch(ch)
				{
				case'<':
					ch=fgetc(in);
					if(ch=='=')
						out("<=",LE);					
					else 
					{
						if(ch=='>')
							out("<>",NE);
						else 
						{
							fseek(in,-1,1);
							out("<",LT);
						}
					}
					break;
				case'=':
					out("=",EQ);					
					break;
				case'>':
					ch=fgetc(in);
					if(ch=='=')
						out(">=",GE);					
					else
					{
						fseek(in,-1,1);
						out(">",GT);
					}
					break;
				case'+':
					out("+",ADD);
					break;
				case'-':
					out("-",MIN);
					break;
				case'*':
					out("*",MUL);
					break;
				case'/': //对注释和除的区分
					ch=fgetc(in);
					if(ch=='*') 
					{
						while(1)
						{ 
							ch=fgetc(in);
							if(ch==EOF)
							{ 
								report_error(4);
								break;
							}
							if(ch=='*')
							{ 
								ch1=ch;
								ch=fgetc(in);
								if(ch=='/')
								{ 
									ch=fgetc(in);
									break;
								}
							}
						}
					}					
					else 
					{
						out("/",DIV);
						break;
					}
				case':':
					ch=fgetc(in);
					if(ch=='=')
						out(":=",EVA);
					break;
				case'(':out("(",LP);
					break;
				case')':
					out(")",RP);
					break;
				case';':
					out(";",SEM);
					break;
				case' ':
					queue++;break;
				case'\t':
					break;	      
				case'\n':
					row++;
					break;					
				default:
					report_error(2);
					break;
				}
			}
		}
	}
}

void main()
{   
	char filename[30];
	cout<<"输入您要编译的文件名:"<<endl;
	cin>>filename;
	if((in=fopen(filename,"rt"))==NULL)
	{
		printf("抱歉您要编译的文件 %s 有问题,请检查。\n",filename);
		exit(1);
	}
	fopen("finish.txt","wr");
	scanner();
	cout<<"**********************************************"<<endl;
	cout<<endl;
	cout<<"错误个数:"<<error_count<<endl;
}

⌨️ 快捷键说明

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