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

📄 cifafenxi.cpp

📁 这是一个编译器程序包括了编译原理中学习的所有内容
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>
#include<stack>
#include<cmath>
#include<vector>
using namespace std;
#define Length 61
#define N      100
#define Size   100
/*************************定义结构********/
 struct token//单词表结构
{
	int label;/*单词序号*/
	char name[30];/*单词本身*/
	int code;//单词的机内码
	int addr;//标识符或常数在符号表中的入口地址
};
 //符号表文件结构
 struct Symble
 {   int number;
	 int type;
	 char name[30];
 };
 vector<string> st;//向量用于回填
//关键字结构
 struct KeyWord
{
	char name[30];
	int code;
};

//产生式结构
 struct ChanShengShi
{
	string left;//左部
	string right;//右部
	int len;
};
//action表结构,栈
 struct  Action
{
	char cha;//栈内字符
	int state;//状态
};
 struct  Data
 {
	 int zt;
	 string word;
 };
stack<token>s1;//token栈
stack<token>s2;//token栈的逆序
stack<string>YuyiStack;
/****************************变量定义*******/
char ch;//字符
int fu_count;//记录三地址的个数
int var_count;//输入字符数
int error_count;//错误个数
int addr_count;
int label_count;//单词序号数
int code_count;//单词机内码数
int LineOfPro;//记录行数
char filename[30];//文件名
int q;
FILE *KeyFin;//关键字文件输入
FILE *SourceFin;//文件输入源
FILE *TokenFout;//分析文件输出
FILE *SymbleFout;
FILE *SdzFout;
KeyWord key[Length];//关键字
token CurrentToken;//
Symble CurrentSymble;
Symble SymbleList[N];
ChanShengShi css[18];//产生式数组
Action action[45][18];//action表
int GoTo[45][8];
string l[N];//字符串数组用于存放三地址的字符串

/**************************函数定义*********/
void ttttt();
void ttt();
void tt();
void ScannerInit();//扫描初始化
void IsAlpha();//判断是不是字符
void IsNumber();//判断是不是数字
void IsAnotation();//判断是不是注释符
void IsChar();//判断是不是字符
void IsOther();//判断是否为其他字符
void OutPut();//输出
void Error(int a);//出错处理
void Scanner();//扫描
int WordHave();
void Analys();//语法分析
void AnalysInit();//语法分析初始化
void InitState();
void InitFuhao();
void pushState(int x);
void pushFuhao(string x);
void popState();
void popFuhao();
string getTop();
int  Fuzhi(int i);
int BianGoto1(string p);
int strcmp(char*s,char*t)//比较函数
{
	 for(;*s==*t;s++,t++)
   if(*s==0)return 0;
   return 1;
}
void huitian(vector<string> & a,int t1,int t2);
int too1;
int kbb;
int to2,to3,to4,to5;
void print(vector<string> a);//打印输出
/***************主程序*******************/
int main()
{

	int i=0,j=0;
	code_count=0;
	too1=0;
	to2=0;
	to3=0;
	to4=0;
	to5=0;
	
	fu_count=0;
	LineOfPro=0;
	addr_count=1;
    var_count=0;
	label_count=1;
	YuyiStack.push("@");
	for(i=0;i<N;i++)
	{   l[i]="\0";
		SymbleList[i].number=0;
		SymbleList[i].type=0;
		for(j=0;j<30;j++)
			SymbleList[i].name[j]='\0';
	}
    Scanner();
	Analys();
	if(to4!=0)
	{
		huitian(st,to2,to4);
		huitian(st,to3,kbb);
		huitian(st,to4,0);
		huitian(st,to5,kbb);
	}
	else
	{
		huitian(st,to2,0);
		huitian(st,to3,kbb);
	}
	print(st);

//	huitian(st,1,3);
//	vector<string>::iterator it=st.begin();
//	cout<<*it<<endl;
//	cout<<to2<<to3<<to4<<to5<<endl;

	
	return 0;
}


/*************词法分析*******************************************/
void Scanner()
{
	int i=0;
	error_count=0;
	ScannerInit();
	printf("        **********************************\n");
    printf("                    编译器\n");
	printf("        **********************************\n");
	printf("输入源文件名:");
	for(;;)
	{
		scanf("%c",&filename[i]);
	   if(filename[i]==10)
		   break;
	   i++;
	}
	filename[i]='\0';
	if((SourceFin=fopen(filename,"rt"))==NULL)
	{
		printf("无法打开文件 %s.\n",filename);
		exit(1);
	}
	if((TokenFout=fopen("token.txt","wt+"))==NULL)
	{
		printf("无法打开文件 token.txt.\n");
		exit(1);
	}
	if((SymbleFout=fopen("symble.txt","wt+"))==NULL)
	{
		printf("无法打开文件 symble.txt\n");
		exit(1);
	}
	printf("词法分析:\n");
	ch=fgetc(SourceFin);//读取第一个字符
	while(ch!=EOF)
	{
		for(i=0;i<30;i++)
			CurrentToken.name[i]='\0';
		if((ch>47)&&(ch<58)) 
		{
			IsNumber();//数字
		}
		else
		{
			if(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))||ch=='_')
			{
				IsAlpha();//字母
			}
			else
			{
				if(ch=='/')
					
				{
					IsAnotation();//注释符
				}
				else if(ch=='\'')
				{
					IsChar();//字符串
				}
				else
			    	IsOther();//其他符号
			}
		}
	}
	fclose(SourceFin);//关闭文件
	fclose(TokenFout);
	fclose(SymbleFout);
	printf("词法分析完毕.\n");
	printf("\n");
}
/****************初始化**********************/
void ScannerInit()
{
	int i=1;
	int k=0;
	if((KeyFin=fopen("jineima.txt","rt"))==NULL)
	{
		printf("Can not open jineima.txt.\n");
		exit(1);
	}
	for(i=0;i<60;i++)
		for(k=0;k<30;k++)
		key[i].name[k]='\0';
	for(i=0;i<60;i++)
	{
		fscanf(KeyFin,"%s%d",key[i].name,&key[i].code);
	}
	fclose(KeyFin);
}
/*********************数字处理**************************/
void IsNumber()
{
	int k=0;
	int flag=0;//标识符
	char ch1;
	while(((ch>47)&&(ch<58)))//字符为数字
	{
		CurrentToken.name[k++]=ch;//记录当前字符
		ch=fgetc(SourceFin);
		if(ch=='.')//字符为小数点
		{
			flag=1;/*为实数标记*/
			break;
		}
	}
	//记录单词编码为整数的编码
	CurrentToken.code=28;//整常数
	CurrentToken.addr=addr_count++;
	CurrentToken.label=label_count++;

	if(flag)//实数
	{
		ch1=fgetc(SourceFin);
		{
			if((ch1>47)&&(ch1<58))
			{
				CurrentToken.name[k++]=ch;
	          	ch=ch1;
		            while((ch>47)&&(ch<58))
					{
			         CurrentToken.name[k++]=ch;
			          ch=fgetc(SourceFin);
					}
		           CurrentToken.code=29;//实常数
			}
		     else Error(2);
		    if(ch=='.')//过滤掉余下的数字
			{
		    	Error(2);
			    ch=fgetc(SourceFin);
		      	while((ch>47)&&(ch<58))
				{
		
			     	ch=fgetc(SourceFin);
				}
			}
			
		}
	}

		if(((ch>64)&&(ch<90))||((ch>96)&&(ch<123)))//当前字符为字母舍去尾部
		{
			Error(2);
			while(((ch>64)&&(ch<90))||((ch>96)&&(ch<123)))
			{
				ch=fgetc(SourceFin);
				while((ch>47)&&(ch<58))
					ch=fgetc(SourceFin);
			}
		}
		OutPut();
}
/************字母处理*******************************/
void IsAlpha()//识别保留字和标识符
{
	int i,h;
	h=0;
	i=0;
	while(((ch>64)&&(ch<90))||((ch>96)&&(ch<123))||ch=='_')
	{
		CurrentToken.name[i++]=ch;//记录当前字符
		ch=fgetc(SourceFin);
	}
	for(i=0;i<Length;i++)
	{
		h=strcmp(CurrentToken.name,key[i].name);//判断所记字符是否为保留字
		if(!h)
			break;
	}
	if(!h)
	{
		CurrentToken.code=key[i].code;
		CurrentToken.addr=-1;
	}
	else
	{
		CurrentToken.code=27;
		CurrentToken.addr=addr_count++;
	}
	CurrentToken.label=label_count++;
	OutPut();
}
/************字符处理*********************************/
void IsChar()
{
	int i=0;
	for(;;)
	{
		ch=fgetc(SourceFin);
		CurrentToken.code=30;
		if(ch!='\'')
			CurrentToken.name[i++]=ch;
		else 
			break;
	}
	CurrentToken.addr=addr_count++;
	CurrentToken.label=label_count++;
	OutPut();
	ch=fgetc(SourceFin);
}
/**********************其他情况*******************************/
void IsOther()
{
	char ch1;
	int i;
	for(i=0;i<30;i++)
		CurrentToken.name[i]='\0';
	switch(ch)
	{ 
	case '(': CurrentToken.name[0]='(';
		      CurrentToken.code=32;
			  CurrentToken.addr=-1;
			  CurrentToken.label=label_count++;
			  OutPut();
			  ch=fgetc(SourceFin);
			  break;
	case ')': CurrentToken.name[0]=')';
		      CurrentToken.code=33;
			  CurrentToken.addr=-1;
			  CurrentToken.label=label_count++;
			  OutPut();
			  ch=fgetc(SourceFin);
			  break;
	case '*': CurrentToken.name[0]='*';
		      CurrentToken.code=34;
			  CurrentToken.addr=-1;
			  CurrentToken.label=label_count++;
			  OutPut();
			  ch=fgetc(SourceFin);
			  break;
	case '+': CurrentToken.name[0]='+';
		      CurrentToken.code=35;
			  CurrentToken.addr=-1;
			  CurrentToken.label=label_count++;
			  OutPut();
			  ch=fgetc(SourceFin);
			  break;
	case '-': CurrentToken.name[0]='-';
		      CurrentToken.code=32;
			  CurrentToken.addr=-1;
			  CurrentToken.label=label_count++;
			  OutPut();
			  ch=fgetc(SourceFin);
			  break;
	case ',': CurrentToken.name[0]=',';
		      CurrentToken.code=37;
			  CurrentToken.addr=-1;
			  CurrentToken.label=label_count++;
			  OutPut();
			  ch=fgetc(SourceFin);
			  break;
	case '.': CurrentToken.name[0]='.';
		      CurrentToken.code=38;
			  CurrentToken.addr=-1;
			  CurrentToken.label=label_count++;
			  OutPut();
			  ch=fgetc(SourceFin);
			  break;

	case ':': ch1=ch;
		ch=fgetc(SourceFin);
		if(ch!='=')
		{
			CurrentToken.name[0]=':';
			CurrentToken.code=40;
			CurrentToken.addr=-1;
			CurrentToken.label=label_count++;
			OutPut();
		}
		else
		{
			CurrentToken.name[0]=':';
			CurrentToken.name[1]='=';
			CurrentToken.code=41;
			CurrentToken.addr=-1;
			CurrentToken.label=label_count++;
			OutPut();
			ch=fgetc(SourceFin);
		}
		break;

	case ';': CurrentToken.name[0]=';';
		      CurrentToken.code=42;
			  CurrentToken.addr=-1;
			  CurrentToken.label=label_count++;
			  OutPut();
			  ch=fgetc(SourceFin);
			  break;

	case '<': ch1=fgetc(SourceFin);
		     if(ch1=='=')
			 {
				 CurrentToken.name[0]='<';
				 CurrentToken.name[1]='=';
				 CurrentToken.code=44;
				 CurrentToken.addr=-1;
				 CurrentToken.label=label_count++;
				 OutPut();
				 ch1=fgetc(SourceFin);
			 }
			 else
			 {
				 if(ch1=='>')
				 {
					 CurrentToken.name[0]='<';
					 CurrentToken.name[1]='>';
					 CurrentToken.code=45;
					 CurrentToken.addr=-1;
					 CurrentToken.label=label_count++;
					 OutPut();
					 ch1=fgetc(SourceFin);
				 }
				 else
				 {
					 CurrentToken.name[0]='<';
					 CurrentToken.code=43;
					 CurrentToken.addr=-1;
					 CurrentToken.label=label_count++;
					 OutPut();
				 }
			 }
			 ch=ch1;
			 break;
	case '=': CurrentToken.name[0]='=';
		      CurrentToken.code=46;
			  CurrentToken.addr=-1;
			  CurrentToken.label=label_count++;
			  OutPut();
			  ch=fgetc(SourceFin);
			  break;
	case'>':ch1=fgetc(SourceFin);
		    if(ch1=='=')
			{
				CurrentToken.name[0]='>';
				CurrentToken.name[1]='=';
				CurrentToken.code=48;
				CurrentToken.addr=-1;
				CurrentToken.label=label_count++;
				OutPut();
				ch1=fgetc(SourceFin);
			}
			else
			{
				CurrentToken.name[0]='>';
				CurrentToken.code=47;
				CurrentToken.addr=-1;
				CurrentToken.label=label_count++;
				OutPut();
			}
			ch=ch1;
			break;
	case '{': CurrentToken.name[0]='{';
		      CurrentToken.code=49;

⌨️ 快捷键说明

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