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

📄 yufa.cpp

📁 编译原理
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "yufa.h"//新建了一个头文件yufa.h 我把函数的申明,以及经常要用的getsym(FILE *fim)函数,以及此程序
				//要用到的变量都放到了这个头文件先读头文件。 里面都是一些简单的定义和实现以及函数申明部分
				//很容易理解的。
 #include <stdlib.h>  
#define stacksize 500
int cx=0;
int p,b,t;
int s[stacksize];
instruction i1;
int isdefine(char *id)
{
	for(int i=ptx;i>=0;i--)
	{
		if(strcmp(table[i].name,id)==0&&table[i].level==Lev)
			return 1;
	}
	return 0;
}
void enter(object k,int *ptx,int lev, int *pdx)//k表示声名的单词类型,ptx指示table数组的当前值
	{//k表示标识符的类型,ptx表示当前table数组的下标,lev表示当前引用层与定义层的层差
		if(lev>3)
			printf("过程嵌套超过了最大值");
		else 
		{
			switch(k)
			{
			case constant:{
							table[(*ptx)].kind=constant;
							(*ptx)++;
							break;
						  }
			case variable:{
							table[(*ptx)].kind=variable;
							table[(*ptx)].level=lev;
							table[(*ptx)].adr=(*pdx);
							varcount++;//...................
							(*ptx)++;
							(*pdx)++;
							break;
						  }
			case procedur:{
							table[(*ptx)].kind=procedur;
							table[(*ptx)].level=Lev;
							table[(*ptx)].size=3;//..................
							varcount=0;
							(*pdx)=3;
							(*ptx)++;
							break;
						  }
			}
		}
	}
//////////////////////////////////////
void gen(fct fct1,int lev,int a1)
{
	code[cx].f=fct1;
	code[cx].l=lev;
	code[cx].a=a1;
	cx++;
}
//////////////////////////////////////////
 int position(char *id)
 {
	for(int i=ptx-1;i>=0;i--)
	{
		if(strcmp(table[i].name,id)==0)
		{
			if(table[i].level<=Lev)
			return i;
		}
	}
	return -1;
 }
 ////////////////////////////////////////////////
void printblank(int k)//输出k个空格,这个函数没有特别的目的,只是为了便于以后的修改而写的
{
	for(int i=1;i<=k;i++)
		printf(" ");
}
void endfunc(char *end)
{
	//调用完某个函数后给出的信息  end  为传递进来的输出信息这个函数也没有特别的目的,只是为了使程序清楚而且
	//能够避免重复的代码要写多遍,这个就相当于一个小的模块。读程序时不需要读这个	
	printblank(k);
	printf("}\n");
	printblank(k);
	k=k-m;
	printf("%s\n",end);		
}
void beginfunc(char *begin)
{
	//这个函数的功能和效果都跟endfunc 差不多的,不过这个是对函数调用时给出的头信息
	//begin 为要给出的头输出信息
	printblank(k);
	printf("%s\n",begin);
	printblank(k);
	printf("{\n");
}
void errorby(int errornum,FILE *fin,char *line)
	{
		//这个函数同上面两个函数一样都是为了是程序修改更方便,即若发现问题只需要在这个模块里面改就可以了
		//这样修改起来会容易些。errornum 为了把错误出现的次数记录下来,做为错误数组(error[])的下标
		//函数中还用到了strcat() 这个函数为字符串连接函数。
		flag=0;
		strcpy(error[errortotal],errortype[errornum]);
		//注释掉下面这两行后测试  与不注释时的区别  就可以知道用这个函数的目的了。
		strcat(error[errortotal]," error in (pl0.txt) on line ");
		strcat(error[errortotal],line);
		errortotal++;
	}
void program(FILE *fin)
	{
	beginfunc("程序开始");
	k=k+m;//每调用一次函数,k就加 m,即输出的空格数加m
	block(fin);	
	if(sym!=dot)
		{
			//errorby(8,fin,lineno);
		}
	endfunc("程序结束");
	}
void block(FILE *fin)
	{	
		int tx0,cx0;//Lev++;
		beginfunc("分程序开始");
		tx0=ptx-1;
		table[tx0].adr=cx;
		gen(jmp,0,0);
		if(sym==constsym)
		{
			k=k+m;
			constsymh(fin);
		}
		if(sym==varsym)
		{
			k=k+m;
			varsymh(fin);
		}
		table[tx0].size=varcount+3;//...........................
		if(sym==proceduresym)
		{
			k=k+m;
			proceduresymh(fin);
		}
		////////////////////////////////////////
		cx0=cx;
		code[table[tx0].adr].a=cx0;
		code[0].a=cx0;
		gen(inte,0,table[tx0].size);
		//////////////////////////////////////
		if(sym!=(symbol)0)
		{
			k=k+m;
			sentence(fin);
		}
		gen(opr,0,0);
		//Lev--;
		endfunc("分程序结束");
	}
void constsymh(FILE *fin)//实现 常量说明部分
	{
		beginfunc("常量说明部分");
		if(sym==constsym)
		{
			sym=getsym(fin);
			k=k+m;
			constdefin(fin);
		}
		while(sym==comma)
		{
			sym=getsym(fin);
			k=k+m;
			constdefin(fin);
		}
		if(sym!=semicolon)
		{
			errorby(4,fin,lineno);//错误处理先不用管它
		}
		else sym=getsym(fin);//向下读单词为以后的程序执行提供识别字符
		endfunc("常量说明部分结束");
	}
void constdefin(FILE *fin)//实现 常量定义
	{
		int flag=0;
		beginfunc("常量定义:");
		if(sym!=ident)
		{
			errorby(3,fin,lineno);//错误处理
		}
		else
		{
			if((flag=isdefine(id))!=1)
			strcpy(table[ptx].name,id);//..................................
			else errorby(26,fin,lineno);
			sym=getsym(fin);
			if(sym!=eql)
			{
				errorby(0,fin,lineno);//错误处理
			}
			else
			{
				sym=getsym(fin);
				if(sym!=number)
				{
					errorby(1,fin,lineno);//错误处理
				}
				else 
				{
					if(flag!=1)
					{
						table[ptx].val=num;//.........................................
						enter(constant,&ptx,Lev,&pdx);//..............................
					}
					sym=getsym(fin);//<常量定义>规则 识别成功向下读单词为以后判断提供新的识别字符
				}
			}
		}
		endfunc("常量定义结束");
	}
void varsymh(FILE *fin)//实现 变量说明部分
	{
		beginfunc("变量说明部分:");//模块化,可先不看他,此函数定义在前面了。
		if(sym==varsym)
		{
			sym=getsym(fin);
			if(sym!=ident)
			{
				errorby(3,fin,lineno);
			}
			else
			{
				strcpy(table[ptx].name,id);//.................................
				enter(variable,&ptx,Lev,&pdx);//....................................
				sym=getsym(fin);
				while(sym==comma)
				{
					sym=getsym(fin);
					if(sym!=ident)
					{
						errorby(3,fin,lineno);
						if(sym==comma) break;
					}
					else 
					{
						strcpy(table[ptx].name,id);//.......................................
						enter(variable,&ptx,Lev,&pdx);//..........................................
						sym=getsym(fin);
					}
				}
				if(sym!=semicolon)
				{
					errorby(4,fin,lineno);
				}
				else sym=getsym(fin);
			}
		}
		endfunc("变量说明部分结束");//同beginfunc("   ");用法和功能
	}
void proceduresymh(FILE *fin)//实现  过程说明部分
	{			
		int count=1;
		beginfunc("过程说明部分");
		if(sym==proceduresym)
		{
			sym=getsym(fin);
			if(sym!=ident)
			{
				errorby(3,fin,lineno);
			}
			else
			{
				strcpy(table[ptx].name,id);//新舔加
				enter(procedur,&ptx,Lev,&pdx);//新舔加
				sym=getsym(fin);
				if(sym!=semicolon)
				{
					errorby(4,fin,lineno);
				}
				else sym=getsym(fin);
				k=k+m;
				Lev++;
				block(fin);
				Lev--;
				while(sym==semicolon)
				{
					sym=getsym(fin);
					k=k+m;
					proceduresymh(fin);
					count++;
				}
				if(count==1)
				{
					if(sym!=semicolon&&sym!=(symbol)0)
					{
						errorby(4,fin,lineno);
					}
				}
			}
		}
		
		endfunc("过程说明部分结束");
	}
void sentence(FILE *fin)//语句的实现
	{
		beginfunc("语句开始");
		if(sym==ident)
		{
			k=k+m;
			statement(fin);
		}
		else if(sym==beginsym)
		{
			k=k+m;
			beginsymh(fin);
		}
		else if(sym==ifsym)
		{
			k=k+m;
			condition(fin);
		}
		else if(sym==whilesym)
		{
			k=k+m;
			whilesymh(fin);
		}
		else if(sym==writesym)
		{
			writesymh(fin);
		}
		else if(sym==readsym)
		{
			k=k+m;
			readsymh(fin);
		}
		else if(sym==callsym)
		{
			k=k+m;
			callsymh(fin);
		}
		else 
		{
			errorby(6,fin,lineno);
			endfunc("语句结束");
			return;
		}
	}
void statement(FILE *fin)// 赋值语句的实现
	{
		int p;//用来记录变量在符号表中的位置
		beginfunc("赋值语句:");
		if(sym==ident)
			{
				///////////////////////////////////
				p=position(id);
				if(p==-1)
				{
					errorby(10,fin,lineno);
				}
				else if(table[p].kind!=variable)
					errorby(11,fin,lineno);
				/////////////////////////////////
				sym=getsym(fin);
				if(sym==becomes)
				{
					sym=getsym(fin);
					expression(fin);
				}
				else 
				{										
					errorby(12,fin,lineno);
				}
				if(p!=-1)
				gen(sto,Lev-table[p].level,table[p].adr);
			}
		else sym=getsym(fin);
		endfunc("赋值语句结束");
		}
void tiaojian(FILE *fin)
	{	
		symbol relop;//..........................................
		if(sym==oddsym)
			{
				sym=getsym(fin);
				expression(fin);
				gen(opr,0,6);
			}
			else
			{	
				expression(fin);
				if(sym!=eql&&sym!=lss&&sym!=leq&&sym!=gtr&&sym!=geq&&sym!=neq)
				{
					errorby(19,fin,lineno);
				}
				else
				{
					relop=sym;//...................................
					sym=getsym(fin);
					expression(fin);
					///////////////////////////////////
					switch(relop)
					{
					case eql:{gen(opr,0,8); break;}
					case neq:{gen(opr,0,9); break;}
					case lss:{gen(opr,0,10);break;}
					case geq:{gen(opr,0,11);break;}
					case gtr:{gen(opr,0,12);break;}
					case leq:{gen(opr,0,13);break;}
					}
					///////////////////////////////
				}
			}
	}
void expression(FILE *fin)//定义表达式函数
	{
		symbol addop;//................................
		if(sym==plus||sym==minus)
		{

⌨️ 快捷键说明

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