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

📄 parse.cpp

📁 该程序是一个MiniPascal语言的编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include<iostream.h>
#include<fstream.h>
#include<stdio.h>
#include<stdlib.h>
#include<iomanip.h>
#include<ctype.h>
#include<string.h>

#include"list.h"
#include"global.h"
#include"keyword.h"
#include"interpret.h"

//----------------------------------------------------------------------------------------------//

//						            语法分析部分

//包括语法分析、符号表的建立与查找、语义分析(错误发现)、目标代码生成等

//----------------------------------------------------------------------------------------------//


//**********************************************************************************************//

//******************************调用函数的声明**************************************************//

//**********************************************************************************************//
void initialtypelist();
bool searchfield(char name[SIZE],struct type_list* mother,struct field_table* child);
int nexttoken();
int search(char name[SIZE],struct proc_list* pro ,struct var_list* var);
bool proc_rename(char name[SIZE]);
bool type_rename(char Typename[SIZE]);
bool field_rename(char fieldname[SIZE]);
int searchtype(char TypeName[SIZE]);
bool isconst(int&);
void error(int,int);
bool var_rename(char varname[SIZE]);
void match(int);
void consdef();
void const_define();
void array_type();
void rec_section();
void record_type();
void newtype();
void typdef();
void type_define();
void varlist(int);
void vardef();
void var_define();
void proc_define();
void block(int&);
void param_define();
void fparam_list();
void proc_define();
void com_sent();
void rparam_list();
void proc_sent();
void if_sent();
void while_sent();
void assign_sent();
void readvar();
void writevar();
void sentence();
void simple_expr(int&);
void term(int&);
void varaccess(int&,int);
void express(int&);
void gene(int&);
bool isrelational_op(int);

//**********************************************************************************************//

//************************函数的实现部分,语法分析和生成代码的主要部分**************************//

//**********************************************************************************************//
//typelist数组1、2、3元素的初始化部分
void initialtypelist()
{
	strcpy(typelist[1].name,"const");//typelist[1]:const
	strcpy(typelist[2].name,"boolean");//typelist[2]:boolean
	strcpy(typelist[3].name,"integer");//typelist[3]:integer
	for(int i=1;i<=3;i++)
	{
		typelist[i].bandwidth=1;
		typelist[i].bandwidthOfelement=0;
		typelist[i].type=i;
		typelist[i].typeofelement=0;
	}
}
void match(int t)
{//匹配向前看符号
	
	int tt;
	if(lookahead==EOF)
	{
		error(33,LINE);
		cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
		exit(0);
	}
	int line=LINE;//记录下';'不匹配时的行号
	if(lookahead!=t)
	{
		tt=lookahead;
		lookahead=t;
		if(t==semicolon)
		{//匹配';'失败
			if(line<LINE)
				error(1,line);
			else error(1,LINE);
			lookahead=tt;
			return;
		}
		else error(1,LINE);//error函数应携带编码信息,编码文件输出相应的出错提示信息!!!
		lookahead=tt;
		if(t==Program)//如果连program都不匹配,则无需再往下判断
		{
			cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
			exit(0);
		}
		
	}  
	 lookahead=nexttoken();
}
//<程序>
void program()
{// <程序> -> Program<程序名>;<块体>·
	int offs,oldp,newp;
	char Progname[SIZE];
	initialtypelist();
	streampos VarPt,temp;
	lookahead=nexttoken();
    match(Program);
//在过程表中添加新表项
	cur_proc->offset=0;//
	cur_proc->level=1;
	cur_proc->father=NULL;
	cur_proc->numofchild=0;
	cur_proc->next=new var_list;
	cur_proc->next=cur_varlist;
	cur_proc->ParamLength=0;
	cur_proc->numofparam=0;
	cur_proc->VarLength=0;
	for(int i=0;i<SIZE;i++)
		cur_proc->NewType[i]=-1;
	cur_proc->numofnewtype=0;
	off=3;

//目标代码生成
	outfile<<25<<' ';//programx()
	int lineno=LINE;
    VarPt=outfile.tellp();
	oldp=pfollow;	
	pfollow+=5;
	outfile<<"                     "<<endl;
	strcpy(Progname,token);
	match(id);
    strcpy(cur_proc->name,Progname);
	match(semicolon);
	block(newp);           //<块体>proccall
	offs=newp-oldp;
	//end of program
	temp=outfile.tellp();
	outfile.seekp(VarPt);
	outfile<<cur_proc->VarLength<<' '<<cur_proc->VarLength*3<<' '<<offs<<' '<<lineno;
	outfile.seekp(temp);
	outfile<<7;//	outfile<<"EndProg;"<<endl;
	match(dot);
	//----------------------判断后面是否还有注释,或者是其他非法内容----------------------//
	//if 注释
	while(lookahead==lbrace)
	{
		match(lbrace);
		while(lookahead!=rbrace)
		{
			
			if(lookahead==EOF)
			{
				error(33,LINE);
				cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
				exit(0);
			}
			match(lookahead);
		}
		match(rbrace);
	}
	//if not
	if(lookahead==EOF||lookahead==dot)
		return;
	else 
	{
		error(33,LINE);
		cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
		exit(0);
	}
}

//<块体>
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//                             块体的语义分析函数
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//uptill携带相关信息返回
void block(int& uptill)
{//<块体> -> [<常数定义部份>][<类型定义部份>][<变量定义部分>]{<过程定义>}<复合语句>
 //   int follow=0;
	if(lookahead==Const)const_define();
    if(lookahead==Type)type_define();
	if(lookahead==Var) var_define();
	
	cur_varlist->type=-1;//终结
	cur_varlist->next=new var_list;//建立新表项
	cur_varlist=cur_varlist->next;
	cur_varlist->type=-1;//尚未填充
	
	cur_proc->VarLength=off-3;//偏移(to b)以3开始
    while(lookahead==Procedure)
		proc_define();
	uptill=pfollow;
	com_sent();//<复合语句> -> begin <语句>{;<语句>}end
}
//<常数定义部分>:
void const_define(){//<常数定义部价> -> cons <常数定义>{常数定义}
	match(Const);
	do{//一个或多个
		consdef();
	}while(lookahead==id);
}
//<常数定义>:
void consdef(){//<常数定义> -> <常数名>=<常数>;
	int consttype;
    strcpy(Constname,token);
	match(id);//<常数名>
	
	if(var_rename(Constname))
	{
		int line=LINE;
		strcpy(errortype,Constname);
		error(0,LINE);
		//出错,一直读到本语句末,这样可继续检查下面的语句
		while(lookahead!=semicolon)
		{
			match(lookahead);
			if(lookahead==Begin)
			{
				error(28,line);
				//cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
				return;
			}
			if(lookahead==EOF)
			{
				error(28,line);
				cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
				exit(0);
			}

		}
		match(semicolon);
		return;
	}
	match(relop_EQ);
//	int flag=0;//是否是负常数
//	if(lookahead==minus_op)
//	{
//		match(minus_op);
//		flag=1;
//	}

	if(!isconst(consttype))
	{//若不是常数
		strcpy(errortype,token);
		error(25,LINE);   //Const Defination Error!
		match(lookahead);//跳过,继续往下
	}
	match(semicolon);
	
	//将新定义的常数添加到符号表当前表项中
	cur_varlist->type=Const;
	cur_varlist->typeofconst=consttype;//0:boolean;1:integer
//	if(flag==0)
		cur_varlist->ConstVal=ConstVal;
//	else cur_varlist->ConstVal=-ConstVal;
    strcpy(cur_varlist->name,Constname);
	cur_varlist->next=new var_list;
	cur_varlist=cur_varlist->next;
	cur_varlist->type=-1;
}
//<类型定义部分>
void type_define(){//<类型定义部份> -> type <类型定义>{类型定义}
	match(Type);
	do{//一个或多个
		typdef();
	}while(lookahead==id);
}
//<类型定义>:
void typdef()
{//<类型定义> -> <类型名>=<新类型>;
	strcpy(Typename,token);
	if(type_rename(Typename))
		error(18,LINE);
	match(id);
	match(relop_EQ);
	newtype();//<新类型>
	match(semicolon);
}
//<新类型>:
void newtype()
{//<新类型> -> <数组类型>|<记录类型>
    if(lookahead==Array)
	{
		array_type();
		cur_proc->numofnewtype++;//定义了个新类型
		return;
	}
	if(lookahead==Record)
	{
		record_type();
		cur_proc->numofnewtype++;//定义了个新类型
		return;
	}
	error(20,LINE);//如果不是则报错
	//------------------------------连续报错----------------------------------------------------//
	int line=LINE;//记录下';'不匹配的行数
	while(lookahead!=semicolon)
	{
		match(lookahead);//
		if(lookahead==Begin)
			{
				error(28,line);
				//cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
				return;
			}
			if(lookahead==EOF)
			{
				error(28,line);
				cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
				exit(0);
			}
	}
}
//<数组类型>:
void array_type()
{//<数组类型> -> array[<下标域>] of <类型名>&<下标域> -> <常数>··<常数>
	//--------->  array[<常数>..<常数>] of <类型名>
	int upper,lower,range;
	int vartype;
	match(Array);    match(lbracket);

	//int flag=0;
	/*if(lookahead==minus_op)
	{
		flag=1;
		error(4,LINE);
		match(minus_op);//一般情况下是这样
	}*/

	bool flag1=isconst(vartype);

	if(flag1==false||vartype==0)
	{
		//cout<<lookahead<<endl;
		error(4,LINE);
		int line=LINE;
		//直到匹配到".."
		while(lookahead!=dotdot)
		{
			match(lookahead);//
			if(lookahead==Begin)
				{
					error(30,line);
					//cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
					return;
				}
				if(lookahead==EOF)
				{
					error(30,line);
					cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
					exit(0);
				}
		}
	}
	//if(flag==0)
		lower=ConstVal;
	//else lower=-ConstVal;
	
	match(dotdot);

	/*if(lookahead==minus_op)
	{
		flag=1;
		error(26,LINE);
		match(lookahead);
	}*/

	bool flag2=isconst(vartype);
	if(flag2==false||vartype==0)
	{
		error(26,LINE);
		int line=LINE;
		//直到匹配到']'
		while(lookahead!=rbracket)
		{
			match(lookahead);//
			if(lookahead==Begin)
				{
					error(31,line);
					return;
				}
				if(lookahead==EOF)
				{
					error(28,line);
					cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
					exit(0);
				}
		}

	}
	//if(flag==0)
		upper=ConstVal;
	//else upper=-ConstVal;

	if(lower>upper)
	{
		error(27,LINE);
		//直到匹配到']'
		int line=LINE;
		while(lookahead!=rbracket)
		{
			match(lookahead);//
			if(lookahead==Begin)
				{
					error(31,line);
					return;
				}
				if(lookahead==EOF)
				{
					error(31,line);
					cout<<progname<<".obj- "<<errorcount<<" error(s)"<<endl;
					exit(0);
				}
		}
	}
	match(rbracket);
	match(Of);
	int lineno=LINE;
    int eletype=searchtype(token);//
	if(eletype<0)
		error(5,lineno);//类型错误
	match(lookahead);
	//添加新表项到typelist中,同时将过程表的NewType数组增加一个项目
	range=upper-lower+1;
	cur_proc->NewType[cur_proc->numofnewtype]=typecount;//序号
	typelist[typecount].bandwidthOfelement=typelist[eletype].bandwidth;
	typelist[typecount].bandwidth=range*typelist[eletype].bandwidth;
	typelist[typecount].upper=upper;
	typelist[typecount].lower=lower;
	typelist[typecount].type=Array;
    strcpy(typelist[typecount].name,Typename);
	typelist[typecount++].typeofelement=eletype;
}
//<记录类型>:
void record_type()
{//<记录类型> -> record<域表>end & <域表> -> <记录节>{;<记录节>}
	//----------> <记录类型> -> record<记录节>{;<记录节>}end
	match(Record);
	//添加新表项到typelist中
	typelist[typecount].type=Record;
	typelist[typecount].bandwidth=0;//initial
	typelist[typecount].fieldlist=new field_table;
	strcpy(typelist[typecount].name,Typename);
	//
    field=typelist[typecount].fieldlist;//field:global var
	field->offset=0;

	rec_section();//<记录节>
	while(lookahead==semicolon){//一个或多个
		match(semicolon);
		rec_section();
	}
	
	match(End);
	cur_proc->NewType[cur_proc->numofnewtype]=typecount;//将过程表的NewType数组增加一个项目
	typecount++;   //
	field->type=-1;//终结
	field->offset=-1;
}
//<记录节>:
void rec_section()
{//<记录节> -> <域名>{,<域名>}:<类型名>
	//对于纪录的域名来说,只需要内部不出现重名就可以了
	int Varcount=0,i;
	char varname[SIZE][SIZE];//域名数组
	int lineno[SIZE];

⌨️ 快捷键说明

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