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

📄 pll.h

📁 实现pl0编译 能够实现简单的编译 满足编译原理的要求
💻 H
📖 第 1 页 / 共 4 页
字号:

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include"pl.h"
int init()//init correctly return 0,else return -1;
{
		//cc=ll=0;
		//ch=0;
		/*fin=fopen("test.pl","r");
		if(fin==NULL)
		{
			printf("can't read the source file!\n");
			return -1;
		}
		fout=fopen("test.out","a+");
		if(fout==NULL)
		{
			printf("can't create the out file!\n");
			return -1;
		}*/
		linenum=0;
		strcpy(&(keyword[0][0]),"begin");
		strcpy(&(keyword[1][0]),"case");
		strcpy(&(keyword[2][0]),"char");
		strcpy(&(keyword[3][0]),"const");
		strcpy(&(keyword[4][0]),"do");
		strcpy(&(keyword[5][0]),"downto");
		strcpy(&(keyword[6][0]),"else");
		strcpy(&(keyword[7][0]),"end");
		strcpy(&(keyword[8][0]),"for");
		strcpy(&(keyword[9][0]),"function");
		strcpy(&(keyword[10][0]),"if");
		strcpy(&(keyword[11][0]),"integer");
		strcpy(&(keyword[12][0]),"of");
		strcpy(&(keyword[13][0]),"plchar");
		strcpy(&(keyword[14][0]),"procedure");
		strcpy(&(keyword[15][0]),"read");
		strcpy(&(keyword[16][0]),"real");
		strcpy(&(keyword[17][0]),"then");
		strcpy(&(keyword[18][0]),"to");
		strcpy(&(keyword[19][0]),"var");
		strcpy(&(keyword[20][0]),"write");



		//keyword symbol inint
		//这个序列与上面keyword的次序是一致的,为了方便对应取值
		keysym[0]=beginsym;
		keysym[1]=casesym;
		keysym[2]=charsym;
		keysym[3]=constsym;
		keysym[4]=dosym;
		keysym[5]=downtosym;
		keysym[6]=elsesym;
		keysym[7]=endsym;
		keysym[8]=forsym;
		keysym[9]=functionsym;
		keysym[10]=ifsym;
		keysym[11]=integersym;
		keysym[12]=ofsym;
		keysym[13]=charsym;
		keysym[14]=proceduresym;
		keysym[15]=readsym;
		keysym[16]=realsym;
		keysym[17]=thensym;
		keysym[18]=tosym;
		keysym[19]=varsym;
		keysym[20]=writesym;
		////////////////
	//下面主要用于在打印符号表时将中间码以字符串形式打出
		//借鉴资料方法,设为一哈希表,简单
		strcpy(&(charcode[lit][0]),"lit");
		strcpy(&(charcode[opr][0]),"opr");
		strcpy(&(charcode[lod][0]),"lod");
		strcpy(&(charcode[sto][0]),"sto");
		strcpy(&(charcode[cal][0]),"cal");
		strcpy(&(charcode[inte][0]),"inte");
		strcpy(&(charcode[jmp][0]),"jmp");
		strcpy(&(charcode[jpc][0]),"jpc");
		strcpy(&(charcode[red][0]),"red");
		strcpy(&(charcode[wrt][0]),"wrt");
		return 0;
	}

//关于错误处理的几个函数,
//主要是关于集合的运算,为了减少错误扩散
//the first one :in_set 
//判断是否在集合中
int in_set(int i,bool *set)
{
	return set[i];
	//如果在集合中,则返回true,1,否则返回false 0,
}
int set_combination(bool *set,bool *seta,bool *setb,int n)
{
	//seta and setb have the same elements n
	int i=0;
	int varnum=0;
	for(i=0;i<n;i++)
	{
		set[i]=seta[i]||setb[i];
	}
	return 0;
}
int set_substrack(bool *set,bool *seta,bool *setb,int n)
{	
	//n is the number of the setb, n of seta >=n
	// pay attention
	int i=0;
	for(i=0;i<n;i++)
	{
		set[i]=seta[i]&&(!setb[i]);
	}
	return 0;
}
int set_multiple(bool *set,bool *seta,bool *setb,int n)
{
	int i;
	for(i=0;i<n;i++)
	{
		set[i]=seta[i]&&setb[i];

	}
	return 0;
}


int getch()
	{
		if(cc==ll)
		{
			if(ch==EOF)
			{
				printf("To the end of the souce file!");
				return -1;
			}
			ll=0;
			cc=0;
			ch=' ';
			while(ch!='\n')
			{
				if(EOF==fscanf(fin,"%c",&ch))
				{
					line[ll]='\0';
					break;
				}
			//	printf("%c",ch);
			//	fprintf(fout,"%c",ch);//write to the file out in order to compare
				line[ll]=ch;//add to the line;
				ll++;//add the length of the read line
			}
			//printf("\n");
		//	fprintf(fout,"%c","\n");
		}
			ch=line[cc];//read from the line ,every time read a char;
			cc++;//move the point forward;
			return 0;//return correctly
}
void close()
{
	if(fin!=NULL)
		fclose(fin);
	if(fout!=NULL)
		fclose(fout);
	if(ftab!=NULL)
		fclose(ftab);
	if(fcode!=NULL)
		fclose(fcode);
}
void printerr(int index)
{
	printf("Error %d :",nerror++);
	printf("in the line %d ",linenum);
	printf(" int the col %d ",cc-1);
	switch(index)
	{
		case 0:printf("the error is :此处应有';'");break;
		case 1:printf("the error is :常量定义缺少'='");break;
		case 2:printf("the error is :实数型定义错误,少'.'");break;
		case 3:printf("the error is :字符定义错误,少'''");break;
		case 4:printf("the error is :无此类型.");break;
		case 5:printf("the error is :标识符后缺少':'");break;
		case 6:printf("the error is :分程序后少';break;'");break;
		case 7:printf("the error is :缺少')'");break;
		case 8:printf("the error is :赋值语句有误,缺少':='");break;
		case 9:printf("the error is :多余'*'");break;
		case 10:printf("the error is :没有then与之匹配");break;
		case 11:printf("the error is :缺少'('");break;
		case 12:printf("the error is :没有downto或to与之匹配.");break;
		case 13:printf("the error is :缺少'end'");break;
		case 14:printf("the error is :该数字位数过长,超出系统限制.");break;
		case 15:printf("the error is :符号定义错误,是否为':='");break;
		case 16:printf("the error is :虚拟机代码过长,超出系统限制.");break;
		case 17:printf("the error is :嵌套层过深,超出系统限制.");break;
		case 18:printf("the error is :过程定义错误,无标识符.");break;
		case 19:printf("the error is :常量定义错误,无标识符.");break;
		case 20:printf("the error is :常量定义错误,其后类型不正确.");break;
		case 21:printf("the error is :变量定义错误.");break;
		case 22:printf("the error is :字符定义错误.");break;
		case 23:printf("the error is :字符串定义错误.");break;
		case 24:printf("the error is :地址越界.");break;
		case 25:printf("the error is :未声明.");break;
		case 26:printf("the error is :赋值语句有误,该对象非变量.");break;
		case 27:printf("the error is :读语句有误.");break;
		case 28:printf("the error is :read应该对已声明的变量进行操作.");break;
		case 29:printf("the error is :write语句定义错误.");break;
		case 30:printf("the error is :标识符定义错误.");break;
		case 31:printf("the error is :过程名应为标识符.");break;
		case 32:printf("the error is :标识符定义错误,无')'");break;
		case 33:printf("the error is :条件语句中无正确关系运算符.");break;
		case 34:printf("the error is :引用错误,无实参.");break;
		case 35:printf("the error is :实参类型不符.");break;
		case 36:printf("the error is :不能直接调用函数.");break;
		case 37:printf("the error is :前后类型不符.");break;
		case 38:printf("the error is :函数名定义应为标志符.");break;
		case 39:printf("the error is :函数定义后应有:.");break;
		case 40:printf("the error is :for后应为标识符.");break;
		case 41:printf("the error is :无:=,标识符应初始化.");break;
		case 42:printf("the error is :无与之匹配的do语句.");break;
		case 43:printf("the error is :case语句定义错误.");break;
		case 44:printf("the error is :无:.");break;
		case 45:printf("the error is :case语句末尾无end与之匹配.");break;
		case 46:printf("the error is :函数无返回值.");break;
	}
	printf("\n");
}
int getsym()
{
	int i,j,k,sw;
	i=0;
	j=0;
	k=0;
	sw=0;
	//char a[maxlen];//has been defined in the pl.h
	while(ch==' '||ch==10||ch==13||ch==9)
	{
		
		if(ch=='\n')// a marco ,which is defined in pl.h   if((getch()==0)return 0 else return -1;
		       linenum++;  
        getchdo;		// becuase this function is used always,so it's a convinent way
	}
	if(ch>='a'&&ch<='z')
	{
		k=0;
		do
		{
			if(k<maxlen)// <10
			{
				a[k]=ch;// a is buffer to keep the word 
				k++;
			}
			getchdo;
		}while(ch>='a'&&ch<='z'||ch>='0'&&ch<='9');
		a[k]=0;//make the last \0
		strcpy(id,a);
		//binary search
		/*i=0;
		j=20;
		do
		{
			printf("get into the loop %d\n",i);
			// now the k is nouse .so can use it again don't have to need a new variable
			k=(i+j)/2;
			if(strcmp(id,keyword[k])<0)
			{
				j=k-1;//the first half;
			}
			if(strcmp(id,keyword[k])>0)
			{
				i=k+1;
			}
			else
			{
				sym=keysym[k];//第一次匹配成功
				break;
			}
		}while(i<=j);
		if(i<=j)
		{
			sym=keysym[k];
		}
		else
		{
			sym=ident;//是一个标识符
		}*/
		for(i=0;i<21;i++)
		{
			if(strcmp(id,keyword[i])==0)
			{
				sym=keysym[i];
				break;
			}
		}
		if(i==21)
			sym=ident;
	}
	//check if it is a number
	else if(ch>='0'&&ch<='9')
		{
			k=0;
			num=0;
			fnum=0.;
			m=0.1;
			//init the value
			sym=integersym;
			//标识符为数字
			do
			{
				num=10*num+(ch-'0');
				k++;
				getchdo;
				if(ch=='.')
					
				{
					getchdo;//说明此处为实数
					while(ch>='0'&&ch<='9')
					{
						sym=realsym;//changer it to real;
						fnum=num+m*(ch-'0');
						m=m/10;
						getchdo;
					}
				}
			}while(ch>='0'&&ch<='9');
			k++;
			if(k>nummax)
			{
				printerr(14);//error 14:位数过长
			}
		}
		else if(ch=='=')
		{
			//printf("here\n");
			sym=eql;
			getchdo;
		}
		else if(ch==':')
			{
				getchdo;
				if(ch=='=')
					//if it is :=
				{
					sym=assign;
					getchdo;
				}

				else
				{
					sym=colon;
				//	printerr(15);
				//don't need to getchdo;
				}
			}
		else if(ch=='<')
			{
				getchdo;
				if(ch=='=')
				{
					sym=leql;
					//it is the <=
					getchdo;
				}
				else if(ch=='>')
				{
					sym=neql;
					getchdo;
				}
				else
				{
					sym=less;
					//pay attention ,here don't need to read again
				}
			}
		else if(ch=='>')
		{
			getchdo;
			if(ch=='=')
			{
				sym=geql;
				getchdo;
			}
			else
			{
				sym=grt;
			}
		}
		else if(ch=='+')
		{
			sym=plus;
			getchdo;
		}
		else if(ch=='-')
		{
			sym=minus;
			getchdo;
		}
		else if(ch=='*')
		{
			sym=multi;
			getchdo;
		}
		else if(ch=='/')
		{
			sym=divid;
			getchdo;
		}
		else if(ch=='(')
		{
			sym=lparen;
			getchdo;
		}
		else if(ch==')')
		{
			sym=rparen;
			getchdo;
		}
		else if(ch==39)//对字符处理
		{
			//sym=squot;
			//getchdo;
			getchdo;//get the next;
			if(ch>='0'||ch<='9'||ch>='a'||ch<='z')
			{
				//为合法字符
				sym=charsym;//vip
				char_buffer=ch;
				//printf("the char_buffer is :%c\n",char_buffer);
				getchdo;
				if(ch!=39)//vip
					printerr(3);
				else
					getchdo;//vip
			}
			else
				printerr(22);

		}
		else if(ch==',')
		{
			sym=comma;
			getchdo;
		}
		else if(ch==';')
		{
			sym=semicolon;
			getchdo;
		}
		else if(ch=='"')
		{
			//sym=quote;
			//getchdo;
			getchdo;
			if(ch>='0'||ch<='9'||ch>='a'||ch<='z')
			{
				while(ch!='"'&&sw<19)
				{
					string_buffer[sw++]=ch;
					getchdo;
				}
				if(sw<=19)
					string_buffer[sw]='\0';
				if(ch!='"')
				{
					printerr(23);
					//return -1;//vip
				}
				else
				{
					sym=stringsym;
					getchdo;
				}
			}
			else
				printerr(23);
		}
		else if(ch=='.')
		{
			getchdo;
			if(ch==0)
			{
				sym=period;
				printf("To Source End!\n");
			}
		}
		return 0;
}
int genecode(enum vmcode x,int y,struct para p,enum typeset type)//generate the code of he vm
{
	if(cx>=500)
	{
		printerr(16);
		return -1;
	}
	code[cx].vc=x;
	code[cx].l=y;
	//code[cx].a=z;
	if(type==integer)
	{
		code[cx].a=p.i;
		code[cx].flag=0;//0 is the integer
	}
	if(type==plchar)
	{
		code[cx].c=p.c;
		code[cx].flag=1;
	}//1 means the char
	if(type==real)
	{
		code[cx].d=p.d;
		code[cx].flag=2;
	}
	cx++;
	return 0;
}

int test(bool *seta,bool *setb,int n)
{
	if(! in_set(sym,seta))
	{
		printerr(4);
		while((!in_set(sym,seta))&&(!in_set(sym,setb)))
		{
			getsymdo;
		}
	}
	return 0;
}

int senantic(int lev,int tx,bool * fsys)            //block function
{
	//pay attention to the firstsym
	//test the right word
	
	int i=0;
	int varnum=0;
	int j=0;
	int dx;
	//相对地址
	int tx0;
	int cx0;
	int rex;//return 
	bool nextlev[keynum];
	bool statement_firstset[keynum];
	bool block_firstset[keynum];

	for(j=0;j<keynum;j++)
		statement_firstset[j]=false;
	for(j=0;j<keynum;j++)
		block_firstset[keynum]=false;

	statement_firstset[beginsym]=true;
	statement_firstset[ifsym]=true;
	statement_firstset[forsym]=true;
	statement_firstset[casesym]=true;
	


	block_firstset[constsym]=true;
	block_firstset[varsym]=true;
	block_firstset[proceduresym]=true;
	block_firstset[functionsym]=true;

	//
	dx=3;//vip 
	tx0=tx;//recode the init position
	table[tx].adr=cx;
	pa.i=0;

	//printf("have get to here.\n");
	
	do_genecode(jmp,0,pa,integer);////
	//getsymdo;
	//sym=constsym;
	//printf("tx=%d\n",tx);
	if(lev>maxlev)
		//overload the level
	{
		printerr(17);
		return -1;
	}
	do//
	{
		if(sym==constsym)
			//const 
		{
			getsymdo;
			do
			{
				//常量处理函数
				//递归调用
				do_deal_constant(&tx,lev,&dx);
				while(sym==comma)
					//define repeatly
				{
					getsymdo;
					//常量处理
					//调用
					do_deal_constant(&tx,lev,&dx);
				}
				if(sym==semicolon)

⌨️ 快捷键说明

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