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

📄 pl0.cpp

📁 编译方法课程设计PL0词法分析
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define norw	13
#define txmax	100
#define nmax	14
#define al		10
#define amax	2047
#define levmax	3
#define cxmax	200
#define stacksize 500

enum symbol {
			 nul,ident,number,plus,minus,times,slash,oddsym,
			 eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,
			 semicolon,period,becomes,beginsym,endsym,ifsym,
			 thensym,whilesym,writesym,readsym,dosym,callsym,
			 constsym,varsym,procsym
			};

enum object {constant,variable,procedur};

enum fct {lit,opr,lod,sto,cal,int0,jmp,jpc};

typedef char alfa[al];

typedef int symset[32];

struct instruction  {
					 fct f;
					 int l;
					 int a;
					};

struct kind_struct  {
					 int level,adr,size;
					};

union kind_union    {
					 int val;
					 kind_struct vp;
					};

struct table_struct {
					 alfa name;
					 object kind;
					 kind_union cvp;
					};

FILE *fa,*fa1,*fa2,*fin,*fout;
int listswitch,num,cc,ll,kk,cx,err,flag_end;
char ch,line[81],mnemonic[8][5];
alfa id,a,fname,word[norw+1];
instruction code[cxmax+1];
symbol sym,wsym[norw+1],ssym[62];
symset declbegsys,statbegsys,facbegsys;
table_struct table[txmax+1];

void error (int);
int  inchar ();
int  innum ();
int  insymbol (symset);
void getsym ();
int  eoln (FILE*);
void getch ();
void gen (fct,int,int);
void reset (symset ss);
void additem (symset,symbol);
void mergeset (symset,symset);
void test (symset,symset,int);
void block (int,int,symset);

void enter (object,int *,int *,int);
//void enter (object k,int tx,int dx,int lev)

int  position (alfa,int);
//int  position (alfa id,int tx)

void constdeclaration (int *,int *,int);
//void constdeclaration (int tx,int dx,int lev)

void vardeclaration (int *,int *,int);
//void vardeclaration (int tx,int dx,int lev)

void listcode (int);
//void listcode (int cx0)

void statement(symset,int,int);
//void statement(symset fsys,int tx,int lev)

void expression (symset,int,int);
//void expression (symset fsys,int tx,int lev)

void term (symset,int,int);
//void term (symset fsys,int tx,int lev)

void factor(symset,int,int);
//void factor(symset fsys,int tx,int lev)

void condition (symset,int,int);
//void condition (symset fsys,int tx,int lev)

void interpret ();
int  base (int,int,int []);

void error (int n)
{
	int i;
	printf("* * * *");
	fprintf(fa1,"* * * *");
	for(i=1;i<3;i++)
	{
		printf("%c",' ');
		fprintf(fa1,"%c",' ');
	}
	printf("!%2d\n",n);
	fprintf(fa1,"!%2d\n",n);
}

int inchar ()
{
	int i,flag=0;
	for(i='a';i<='z';i++)
		if(ch==i) flag=1;
	return flag;
}

int innum ()
{
	int i,flag=0;
	for(i='0';i<='9';i++)
		if(ch==i) flag=1;
	return flag;
}

int insymbol (symset ss)
{
	int i,flag=0;
	for(i=0;i<=31;i++)
		if(ss[sym]) flag=1;
	return flag;
}

int line_end_of_dot()
{
	int i=0;
	while(i<81)
	{
		if(line[i]=='.')
			return 1;
		i++;
	}
	return 0;
}

void getsym ()
{
	int i,j,k;
	while (ch==' ')
		getch();
	if(inchar())
	{
		k=0;
		//if(line[3]!='.')
		//{
		//	strcpy(a,"end      ");
		//	a[9]=' ';
		//}
		//else
		do
		{
			if(k<al)
			{
				a[k]=ch;
				k++;
			}
			getch();//&&line[3]!='.'
			if(line_end_of_dot()&&!flag_end)
			{
				flag_end=1;
				break;
			}
		}while(inchar()||innum());//strncmp(line,"end.",4)
		if(k>=kk)
			kk=k;
		else 
			do
			{
				kk--;
				a[kk]=' ';
			}while(kk!=k);
		strcpy(id,a);
		i=1;
		j=norw;
		while(i<=j)
		{
			k=(i+j)/2;
			if(strncmp(id,word[k],10)<0)
				j=k-1;
			else if(strncmp(id,word[k],10)>0)
				i=k+1;
			else
				break;
		}
		if(i<=j)
			sym=wsym[k];
		else
			sym=ident;
	}
	else
	{
		if(innum())
		{
			k=0;
			num=0;
			sym=number;
			do
			{
				num=10*num+ch-'0';
				k++;
				getch();
			}while(innum());
			if(k>nmax)
				error(30);
		}
		else
		{
			if(ch==':')
			{
				getch();
				if(ch=='=')
				{
					sym=becomes;
					getch();
				}
				else
					sym=nul;
			}
			else
			{
				if(ch=='<')
				{
					getch();
					if(ch=='=')
					{
						sym=leq;
						getch();
					}
					else
						sym=lss;
				}
				else
				{
					if(ch=='>')
					{
						getch();
						if(ch=='=')
						{
							sym=geq;
							getch();
						}
						else
							sym=gtr;
					}
					else
					{
						sym=ssym[ch];
						getch();
					}
				}
			}
		}
	}
}
/*
int eoln (FILE* fp)
{
	long i=0;
	int c;
	if((c=fgetc(fp))=='\r')
	{
		if((c=fgetc(fp))=='\n')
			return 1;
		else
			i++;
	}
	else
		i++;
	fseek(fp,-i,SEEK_CUR);
	return 0;
}
*/
int eoln (FILE* fp)
{
	long i=0;
	int c;
	if((c=fgetc(fp))==10)
//	{
//		flag_end=1;
		return 1;
//	}
	else
//	{
//		flag_end=0;
		i++;
//	}
	fseek(fp,-i,SEEK_CUR);
	return 0;
}

void getch ()
{
	int i;
	if(cc==ll)
	{
		if(feof(fin))
		{
			printf("program incomplete\n");
			fclose(fin);
			printf("\n");
			exit(0);
		}
		ll=0;
		cc=0;
//		printf("%4d ",cx);
//		fprintf(fa1,"%4d ",cx);
		for(i=0;i<81;i++)
			line[i]=' ';
		while(!eoln(fin))
		{
			ch=fgetc(fin);
//			if(ch=='.')
//				flag_end=1;
			printf("%c",ch);
			fprintf(fa1,"%c",ch);
			line[ll]=ch;
			ll++;
		}
		printf("\n");
//		ll++;
//		line[ll]=fgetc(fin);
		fprintf(fa1,"\n");
	}
	ch=line[cc];
	cc++;
}
/*
void getch ()
{
	int i,flag_end=0;
	if(cc==ll)
	{
		if(feof(fin))
		{
			printf("program incomplete\n");
			fclose(fin);
			printf("\n");
			exit(0);
		}
		ll=0;
		cc=0;
//		printf("%4d ",cx);
//		fprintf(fa1,"%4d ",cx);
		for(i=0;i<81;i++)
			line[i]=' ';
		while(!eoln(fin))
		{
			ch=fgetc(fin);
			if(ch=='.')
				flag_end=1;
//			if(ch=='.')
//				flag_end=1;
			printf("%c",ch);
			fprintf(fa1,"%c",ch);
			line[ll]=ch;
			ll++;
		}
		printf("\n");
//		ll++;
//		line[ll]=fgetc(fin);
		fprintf(fa1,"\n");
	}
	if(flag_end)
		ch=' ';
	else
		ch=line[cc];
	cc++;
}
*/

void gen (fct x,int y,int z)
{
	if(cx>cxmax)
	{
		printf("program too long\n");
		fclose(fin);
		printf("\n");
		exit(0);
	}
	code[cx].f=x;
	code[cx].l=y;
	code[cx].a=z;
	cx++;
}

void reset (symset ss)
{
	int i;
	for(i=0;i<=31;i++)
		ss[i]=0;
}

void additem (symset ss,symbol sb)
{
	ss[sb]=1;
}

void mergeset (symset s1,symset s2)
{
	int i;
	for(i=0;i<=31;i++)
		if(s2[i]&&!s1[i])
			s1[i]=1;
}

void test (symset s1,symset s2,int n)
{
	symset sstemp;
	if(!insymbol(s1))
	{
		error(n);
		if(s1==facbegsys)
		{
			reset(sstemp);
			mergeset(sstemp,s1);
			mergeset(sstemp,s2);
			while(!insymbol(sstemp))
				getsym();
		}
		else
		{
			mergeset(s1,s2);
			while(!insymbol(s1))
				getsym();
		}
	}
}

void block (int lev,int tx,symset fsys)
{
	int dx,tx0,cx0;
	symset ss;
	dx=3;
	tx0=tx;
	table[tx].cvp.vp.adr=cx;
	gen(jmp,0,0);
	if(lev>levmax)
		error(32);
	do
	{
		if(sym==constsym)
		{
			getsym();
			do
			{
				constdeclaration(&tx,&dx,lev);
				while(sym==comma)
				{
					getsym();
					constdeclaration(&tx,&dx,lev);
				}
				if(sym==semicolon)
					getsym();
				else
					error(5);
			}while(sym==ident);
		}
		if(sym==varsym)
		{
			getsym();
			do
			{
				vardeclaration(&tx,&dx,lev);
				while(sym==comma)
				{
					getsym();
					vardeclaration(&tx,&dx,lev);
				}
				if(sym==semicolon)
					getsym();
				else
					error(5);
			}while(sym==ident);
		}
		while(sym==procsym)
		{
			getsym();
			if(sym==ident)
			{
				enter(procedur,&tx,&dx,lev);
				getsym();
			}
			else
				error(4);
			if(sym==semicolon)
				getsym();
			else
				error(5);
			reset(ss);
			additem(ss,semicolon);
			mergeset(ss,fsys);
			block(lev+1,tx,ss);
			if(sym==semicolon)
			{
				getsym();
				reset(ss);
				additem(ss,ident);
				additem(ss,procsym);
				mergeset(ss,statbegsys);
				test(ss,fsys,6);
			}
			else
				error(5);
		}
		reset(ss);
		additem(ss,ident);
		mergeset(ss,statbegsys);
		test(ss,declbegsys,7);
	}while(insymbol(declbegsys));
	code[table[tx0].cvp.vp.adr].a=cx;
	table[tx0].cvp.vp.adr=cx;
	table[tx0].cvp.vp.size=dx;
	cx0=cx;
	gen(int0,0,dx);
	reset(ss);
	additem(ss,semicolon);
	additem(ss,endsym);
	mergeset(ss,fsys);
	statement(ss,tx,lev);
	gen(opr,0,0);
	reset(ss);
	test(fsys,ss,8);
	listcode(cx0);
}

void enter (object k,int *tx,int *dx,int lev)
{
	(*tx)++;
	strcpy(table[*tx].name,id);
	table[*tx].kind=k;
	switch(k)
	{
		case constant:
			 if(num>amax)
			 {
			     error(31);
				 num=0;
			 }
			 table[*tx].cvp.val=num;
			 break;
		case variable:
			 table[*tx].cvp.vp.level=lev;
			 table[*tx].cvp.vp.adr=*dx;
			 (*dx)++;
			 break;
		case procedur:
			 table[*tx].cvp.vp.level=lev;
	}
}

int position (alfa id,int tx)
{
	int i;
	strcpy(table[0].name,id);
	i=tx;
	while(strncmp(table[i].name,id,10))
		i--;
	return i;
}

void constdeclaration (int *tx,int *dx,int lev)
{
	symset ss;
	if(sym==ident)
	{
		getsym();
		reset(ss);
		additem(ss,eql);
		additem(ss,becomes);
		if(insymbol(ss))
		{
			if(sym==becomes)
				error(1);
			getsym();
			if(sym==number)
			{
				enter(constant,tx,dx,lev);
				getsym();
			}
			else 
				error(2);
		}
		else 
			error(3);
	}
	else 
		error(4);
}

void vardeclaration (int *tx,int *dx,int lev)
{
	if(sym==ident)
	{
		enter(variable,tx,dx,lev);
		getsym();
	}
	else
		error(4);
}

void listcode (int cx0)
{
	int i;
	if(listswitch)
	{
		for(i=cx0;i<cx;i++)
		{
			printf("%3d %s%3d%5d\n",i,mnemonic[code[i].f],code[i].l,code[i].a);
			fprintf(fa,"%3d %s%3d%5d\n",i,mnemonic[code[i].f],code[i].l,code[i].a);
		}
	}
}

void statement(symset fsys,int tx,int lev)
{
	int i,cx1,cx2;
	symset ss;
	if(sym==ident)
	{
		i=position(id,tx);
		if(i==0)
			error(11);
		else
			if(table[i].kind!=variable)
			{
				error(12);
				i=0;
			}
		getsym();
		if(sym==becomes)
			getsym();
		else 
			error(13);
		expression(fsys,tx,lev);
		if(i!=0)

⌨️ 快捷键说明

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