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

📄 预测分析.cpp

📁 也是一个编译前端
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <fstream>
#include <iostream>
#include <string>   
using    namespace   std;  


#define max_id	256		//标识符最大长度;
#define stack_size	90	//栈的大小;
#define max_in  90    //输入存放数组的大小;
struct token_x{
char id;
char val[max_id];

};		//符号表表项的结构体定义;

#define max_buf 1024	//缓冲区大小;
#define symmax 100		//符号表长度;
#define tokmax 200		//记号表长度;
struct entry
{
	char var[max_id];
	char id;
	void *addr;	//存放内存地址(2字节),地址标识范围为0-65535
	int type;	//用于记录标识符的类型,1表示整型,0表示字符型;
	
}symtable[symmax];		//符号表表项及声明;
struct token
{	char id;
	entry *ptr;
}toktable[tokmax];		//token字表表项结构体声明;
char buff[1024]={'\0'};	//全局变量,存储经过预处理后的源代码;



void ex_process(char *filename)		//预处理函数,参数值为源代码文件的句柄;
{	ifstream infile(filename,ios::in);
	char old_ch='\0',ch;
	int i=0;
	int flag=0;
	bool in_comment=false;
	while(infile.read(&ch,sizeof(char)))
	{	switch(in_comment)
		{	case false:
				if(old_ch=='/'&&ch=='*')	//遇到注释前标符则将注释标志变量值为真;	
				{	in_comment=true;
					i--;
					i--;
				}
				else if(ch=='\t'||ch=='\n'||ch==' ')	//将制表符,换行符换为空格;
				{	buff[i]=' ';
				}
				else if(ch>='A'&&ch<='Z')
				{	buff[i]=ch+32;
				}
				else 
				{	buff[i]=ch;
				}
				break;
			case true:						//注释标志变量值为真则忽略注释中的字符	
				if(old_ch=='*'&&ch=='/')	//遇到注释结束符将注释标志变量复位,跳出注释
					in_comment=false;
				i--;	
				break;
	}
//	cout<<ch;
	i++;
	old_ch=ch;
	}
	buff[i]='#';
	cout<<buff<<endl;
}
void concat(char temp[],char c)		//连接函数,将字符c连接到字符数组temp的末尾	
{	for(int i=0;temp[i]!='\0';i++)
	{	}
	temp[i]=c;
	temp[++i]='\0';
		}
char ifkey(char *t)		
/*查找函数,查找字符串t是否为源语言中的关键字
是则返回对应关键字的记号,否则则返回标识符记号'i'*/
{	char *table[]={"if","else","return","break","do","while","case","bool","true","false",
					"int","char","then","void","for"};
	char code[]={"0123456789abcde"};
	int i;
	int a=strlen(code);
	for(i=0;i<a;i++)
		if(strcmp(table[i],t)==0)	return code[i];
	return 'i';
	}
struct entry idscan(void)	//扫描函数,返回一个符号表表项的结构体
{	char temp[max_id]={'\0'};
	entry temp_entry={'\0',"NUL"};
	static int i=0;
	temp[0]=0;
	while(buff[i]==' ')
			i++;
	if(buff[i]>='a'&&buff[i]<='z')	//扫描标识符;
		{	while(buff[i]>='a'&&buff[i]<='z'||buff[i]>='0'&&buff[i]<='9')
			{	concat(temp,buff[i]);
				i++;
			}
			temp_entry.id=ifkey(temp);
			strcpy(temp_entry.var,temp);
			return temp_entry;
				}
	else if(buff[i]>='0'&&buff[i]<='9')//扫描数字;
		{	if(buff[i]=='0')
			{	concat(temp,buff[i]);
				i++;
				if(buff[i]=='.')
				{	i++;
						while(buff[i]>='0'&&buff[i]<='9')
					{	concat(temp,buff[i]);
						i++;
					}
				}
			}
			else
				while(buff[i]>='0'&&buff[i]<='9')
				{	concat(temp,buff[i]);
					i++;
					if(buff[i]=='.')
					{	i++;
							while(buff[i]>='0'&&buff[i]<='9')
						{	concat(temp,buff[i]);
							i++;
						}
					}
				}
			if(buff[i]=='e')
			{	i++;
				if(buff[i]=='+'||buff[i]=='-')
				{	i++;
					while(buff[i]>='0'&&buff[i]<='9')
					{	concat(temp,buff[i]);
						i++;
					}
				}
				else
					i--;

			}
			temp[i]='\0';
			temp_entry.id='n';
			strcpy(temp_entry.var,temp);
	
			return temp_entry;
		}
	else		//扫描界符; 
		{	switch(buff[i])
			{	case ',':
					temp_entry.id=',';
					break;
				case ';':
					temp_entry.id=';';
					break;
				case '(':
					temp_entry.id='(';
					break;
				case ')':
					temp_entry.id=')';
					break;
				case '!':
					if(buff[++i]=='=')	
					{	temp_entry.id='w';		//	!=的id为w;
					}
					else
					{	temp_entry.id='!';
						i--;
					}
					break;
				case '=':
					if(buff[++i]=='=')	
					{	temp_entry.id='z';		//	==的id为z;
					}
					else
					{	temp_entry.id='=';
						i--;
					}
					break;
				case '&':
					if(buff[++i]=='&')
					{	temp_entry.id='&';
					}
					else
					{	temp_entry.id='&';
						i--;
					}
					break;
				case '+':
					if(buff[++i]=='+')
					{	temp_entry.id='u';		//++的id为u;
					}
					else
					{	temp_entry.id='+';
						i--;
					}
					break;
				case '<':
					if(buff[++i]=='=')	
					{	temp_entry.id='x';		//	<=的id为x;
					}
					else
					{	temp_entry.id='<';
						i--;
					}
					break;
				case '>':
					if(buff[++i]=='=')	
					{	temp_entry.id='y';		//	>=的id为y;
					}
					else
					{	temp_entry.id='>';
						i--;
					}
					break;
				case '-':
					if(buff[++i]=='-')	
					{	temp_entry.id='v';		//	--的id为v;
					}
					else
					{	temp_entry.id='-';
						i--;
					}
					
					break;
				case '*':
					temp_entry.id='*';
					break;
				case '/':
					temp_entry.id='/';
					break;
				case '#':
					temp_entry.id='#';
					break;
				case '{':
					temp_entry.id='{';
					break;
				case '}':
					temp_entry.id='}';
					break;
				default:
					cout<<"出错!语言中无此字符"<<buff[i]<<endl;	//界符不识别则报错;
					exit(0);
					break;
						}
				i++;
				strcpy(temp_entry.var,"NUL");
				return temp_entry;
	
		}

}
int symnum=0,toknum=0;	//全局变量定义符号表指针及记号表指针;
int search(string a)	//查找函数,若标识符已在符号表中则返回其在符号表中的位置,否则返回-1;
{	for(int i=0;i<symnum;i++)
		if(a==symtable[i].var)	return i;
	return -1;
}
int  insert(void)		//将idscan返回的结构体插入符号表和记号表;
{
	entry temp_entry={'\0',"NUL"};
	while(1)
	{	temp_entry=idscan();
		if(temp_entry.id=='n'||temp_entry.id=='i')
		{	if(symnum+1>=symmax||toknum+1>=tokmax)
			{	cout<<"符号表或记号表空间不足!出错!"<<endl;
				return 0;
			}
			if(search(temp_entry.var)==-1)	//若当前标识符不在符号表中则将其插入;
			{	symtable[symnum]=temp_entry;
				
				toktable[toknum].id=temp_entry.id;
				toktable[toknum].ptr=&symtable[symnum];
				symtable[symnum].addr=toktable[toknum].ptr;
				symnum++;
				toknum++;
			}
			else				//否则只将当前字符插入token表,表项指针指向已存在的符号表表项
			{	int a=search(temp_entry.var);
				toktable[toknum].id=temp_entry.id;
				toktable[toknum].ptr=&symtable[a];
					toknum++;
			}
		}
		else
		{	if(toknum+1>=tokmax)
			{	cout<<"记号表空间不足!出错!"<<endl;
				return 0;
			}
			toktable[toknum].id=temp_entry.id;
			toktable[toknum].ptr=NULL;
			toknum++;
		}
		if(temp_entry.id=='#') break;
	}
	return 1;
}
void display(void)	//显示函数,输出符号表和记号表到文件;
{	
	ofstream outfile1("id.txt",ios::out);
	for(int i=0;i<symnum;i++)
	{	outfile1<<symtable[i].var<<'\t'<<symtable[i].id<<endl;
	}

	ofstream outfile2("token.txt",ios::out);
	for(i=0;i<toknum;i++)
	{//	cout<<toktable[i].id;
		outfile2<<toktable[i].id<<'\t'<<toktable[i].ptr<<endl;
	}

}
int cifamain()
{	char filename[40];
	cout<<"请输入源代码文件名:";
	cin>>filename;
//	cout<<filename;
	ex_process(filename);
	insert();
	display();
	return 0;

	}
char row[]={"QPLDVEWTFBMSNRX"};       //预测分析表的行标号;
char collumn[]={"i()a;+*>&=0c54{}n$"};  //预测分析表的列标号;
int M[15][20]={ {0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,-1,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,-1,-1,-1},
				{-1,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{-1,-1,6,-1,6,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{7,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,7,-1},
				{-1,-1,9,-1,9,9,8,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{10,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10,-1},
				{12,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,23,-1},
				{13,13,-1,-1,-1,-1,-1,-1,14,-1,-1,15,-1,15,-1,-1,13,-1},
				{16,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
				{19,-1,-1,-1,-1,-1,-1,-1,-1,-1,17,-1,18,-1,-1,-1,-1,-1},
				{21,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,-1,21,-1,-1,20,-1,-1},
				{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1,-1,-1},
				{24,24,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,-1,24,-1}
				};

const char *q[]={"Q→P","P→i()L;R","L→DL","L→$","D→ai;","V→+TV","V→$","E→TV"
				,"W→*FW","W→$","T→FW","F→(E)","F→i","B→XB","B→&B","B→$","M→i=E"
				,"S→if B then M","S→while B do M","S→M","N→$","N→S;N","R→{N}","F→n","X→F>F"};
const char *p[]={"P","RL)(i","LD","\0",";ia","VT+","\0","VT"
				,"WF*","\0","WF",")E(","i","BX","B&","\0","E=i"
				,"McB0","M4B5","M","\0","N;S","}N{","n","F>F"};
//	for-e,while-5,do-4,if-0,else-1,++-u,---v,>=-y,<=-x,==-z,!=-w,then-c,int-a
/*文法产生式;
0.Q→P
1.P→i()LR
2.L→DL
3.L→$
4.D→ai;
5.V→+TV
6.V→$
7.E→TV
8.W→*FW
9.W→$
10.T→FW
11.F→(E)
12.F→i
13.B→XB
14.B→&B
15.B→$
16.M→i=E
17.S→if B then M
18.S→while B do M
19.S→M
20.N→$
21.N→S;N
22.R→{N}
23.F→n
24.X→F>F
*/
struct siyuanshi//语义四元式的数据结构
{

	string op;//操作符
	string arg1;//操作数
	string arg2;//操作数
	string result;//结果

}stable[200];
int s_ptr;		//四元式指针;
struct L		//真链与假链项的数据结构;
{	int a;		//标记真链或假链中的四元式标号;
	L *next;	//指向下个节点的指针;
};
L *Ltrue,*Lfalse;//真链与假链的链首指针;
string tval_table[1024];	//临时变量表;
int tval_ptr=0;	//临时变量序号指针;
string id_name,id0_name,id1_name,id2_name,E_name,T_name,F_name,plus_name,mul_name,V_name,W_name;
int err=0,id_then,id_do,id_while;
struct S
{	int position;
	int num;
};
S yuyi_stack[200];	//定义产生式调用寄存栈;
int stack_ptr=0;
int lookup(string m)//检查变量是否已经声明
{
	for(int i=0;i<symnum;i++)
	{	if(symtable[i].var==m)	break;
	}
	if(symtable[i].type==1)
		return 1;
	else
		return 0;
}

string newop(int m)//数字变成字符串生成临时变量;
{
	int shang,yushu;
	string chuan,chuan1;
	shang=m;
	chuan="";
	while(1)
	{
		yushu=shang%10;
		chuan=chuan+char(48+yushu);
		shang=shang/10;
		if(shang==0)
			break;
	}
	int i;
	char *ch;
	ch=&chuan[0];
	chuan1="";
	for(i=strlen(ch)-1;i>=0;i--)
			chuan1=chuan1+chuan[i];
	return(chuan1);
}

⌨️ 快捷键说明

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