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

📄 yufa.cpp

📁 c++_pl0词法分析器
💻 CPP
字号:
#include "yufa.h"
#include "errors.h"
#include "cifa.h"
#include "biaoge.h"
#include "daima.h"

CYufa::CYufa(CPlCompiler *p)
{
	pl=p;
	declbegsys+=constsym;
	declbegsys+=varsym;
	declbegsys+=procsym;
	statbegsys+=beginsym;
	statbegsys+=callsym;
	statbegsys+=ifsym;
	statbegsys+=whilesym;
	statbegsys+=repeatsym;
	facbegsys+=ident;
	facbegsys+=number;
	facbegsys+=lparen;
}
void CYufa::Analysis()
{
	getsym();
	lev=-1;
	CSymbolSet s;
	s=declbegsys;
	s+=statbegsys;
	s+=period;
	block(s);
}
void CYufa::test(CSymbolSet s1,CSymbolSet s2,int n)
{
	if (!s1.InSet(sym))
	{
		pl->errors->Add(n);
		s1+=s2;
		while (!s1.InSet(sym)) getsym();
	}
}
void CYufa::block(CSymbolSet fsys)
{
	lev++;

	int tx0,cx0;
	CSymbolSet s;
	CErrors *err=pl->errors;
	CDaima *dm=pl->daima;
	CBiaoge *bg=pl->biaoge;

	dx[lev]=3;
	tx0=bg->TableIndex();
	bg->table[tx0].adr=dm->cx;
	dm->Gen(jmp,0,0);
	if (lev>MAX_LEVEL) err->Add(32);
	do{
		if (sym==constsym)
		{
			getsym();
			do{
				constdeclaration();
				while (sym==comma)
				{
					getsym();
					constdeclaration();
				}
				if (sym==semicolon) getsym(); else err->Add(5);
			}while (sym==ident);
		}
		if (sym==varsym)
		{
			getsym();
			do{
				vardeclaration();
				while (sym==comma)
				{
					getsym();
					vardeclaration();
				}
				if (sym==semicolon) getsym(); else err->Add(5);
			}while (sym==ident);
		}
		while (sym==procsym)
		{
			getsym();
			if (sym==ident)
			{
				bg->Enter(procedure);
				getsym();
			}
			else err->Add(4);
			if (sym==semicolon) getsym(); else err->Add(5);
			s=fsys;
			s+=semicolon;
			block(s);
			if (sym==semicolon)
			{
				getsym();
				s=statbegsys;
				s+=ident;
				s+=procsym;
				test(s,fsys,6);
			}
			else
				err->Add(5);
		}
		s=statbegsys;
		s+=ident;
		test(s,declbegsys,7);
	}while (declbegsys.InSet(sym));

	dm->code[bg->table[tx0].adr].a=dm->cx;
	bg->table[tx0].adr=dm->cx;
	bg->table[tx0].size=dx[lev];
	cx0=dm->cx;
	dm->Gen(intint,0,dx[lev]);
	s=fsys;
	s+=semicolon;
	s+=endsym;
	statement(s);
	dm->Gen(opr,0,0);
	test(fsys,CSymbolSet(),8);

	lev--;
}
void CYufa::constdeclaration()
{
	CErrors *err=pl->errors;
	CBiaoge *bg=pl->biaoge;

	if (sym==ident)
	{
		getsym();
		if (sym==eql || sym==becomes)
		{
			if (sym==becomes)
				err->Add(1);
			getsym();
			if (sym==number)
			{
				bg->Enter(constant);
				getsym();
			}
			else
				err->Add(2);
		}
		else
			err->Add(3);
	}
	else
		err->Add(4);
}
void CYufa::vardeclaration()
{
	CErrors *err=pl->errors;
	CDaima *dm=pl->daima;
	CBiaoge *bg=pl->biaoge;

	if (sym==ident)
	{
		bg->Enter(variable);
		dx[lev]++;
		getsym();
	}
	else
		err->Add(4);
}
void CYufa::factor(CSymbolSet fsys)
{
	int i;
	CErrors *err=pl->errors;
	table_type *table=pl->biaoge->table;
	CDaima *dm=pl->daima;

	test(facbegsys,fsys,24);
	while (facbegsys.InSet(sym))
	{
		switch (sym)
		{
		case ident:
			i=pl->biaoge->Position(pl->cifa->id);
			if (i==0)
				err->Add(11);
			else
			{
				switch (table[i].kind)
				{
				case constant:
					dm->Gen(lit,0,table[i].val);
					break;
				case variable:
					dm->Gen(lod,lev-table[i].level,table[i].adr);
					break;
				case procedure:
					err->Add(21);
					break;
				}
			}
			getsym();
			break;
		case number:
			if (pl->cifa->num>MAX_NUMBER)
			{
				err->Add(31);
				pl->cifa->num=0;
			}
			dm->Gen(lit,0,pl->cifa->num);
			getsym();
			break;
		case lparen:
			getsym();
			expression(fsys+=rparen);
			if (sym==rparen)
				getsym();
			else
				err->Add(22);
			break;
		}
		test(fsys,facbegsys,23);
	}
}
void CYufa::term(CSymbolSet fsys)
{
	symbol mulop;
	CSymbolSet symset;
	symset+=fsys;
	symset+=times;
	symset+=slash;

	factor(symset);
	while (sym==times||sym==slash)
	{
		mulop=sym;
		getsym();
		factor(symset);
		if (mulop==times)
			pl->daima->Gen(opr,0,4);
		else
			pl->daima->Gen(opr,0,5);
	}
}
void CYufa::expression(CSymbolSet fsys)
{
	symbol addop;
	CSymbolSet symset;
	symset+=fsys;
	symset+=plus;
	symset+=minus;

	if (sym==plus||sym==minus)
	{
		addop=sym;
		getsym();
		term(symset);
		if (addop==minus)
			pl->daima->Gen(opr,0,1);
	}
	else
		term(symset);

	while (sym==plus||sym==minus)
	{
		addop=sym;
		getsym();
		term(symset);
		if (addop==plus)
			pl->daima->Gen(opr,0,2);
		else
			pl->daima->Gen(opr,0,3);
	}
}
void CYufa::condition(CSymbolSet fsys)
{
	symbol relop;
	CSymbolSet s1,s2;
	s1+=eql;
	s1+=neq;
	s1+=lss;
	s1+=leq;
	s1+=gtr;
	s1+=geq;

	if (sym==oddsym)
	{
		getsym();
		expression(fsys);
		pl->daima->Gen(opr,0,6);
	}
	else
	{
		s2+=s1;
		expression(s2+=fsys);
		if (!s1.InSet(sym))
			pl->errors->Add(20);
		else
		{
			relop=sym;
			getsym();
			expression(fsys);
			switch (relop)
			{
			case eql:pl->daima->Gen(opr,0,8);break;
			case neq:pl->daima->Gen(opr,0,9);break;
			case lss:pl->daima->Gen(opr,0,10);break;
			case geq:pl->daima->Gen(opr,0,11);break;
			case gtr:pl->daima->Gen(opr,0,12);break;
			case leq:pl->daima->Gen(opr,0,13);break;
			}
		}
	}
}
void CYufa::statement(CSymbolSet fsys)
{
	int i,cx1,cx2;
	table_type *table=pl->biaoge->table;
	CErrors *err=pl->errors;
	CDaima *dm=pl->daima;
	CSymbolSet s,s2;

	switch (sym)
	{
	case ident:
		i=pl->biaoge->Position(pl->cifa->id);
		if (i==0)
			err->Add(11);
		else if (table[i].kind!=variable)
		{err->Add(12);i=0;}
		getsym();
		if (sym==becomes)
			getsym();
		else
			err->Add(13);
		expression(fsys);
		if (i>0)
			dm->Gen(sto,lev-table[i].level,table[i].adr);
		break;
	case readsym:
		getsym();
		if (sym!=lparen)
			err->Add(34);
		else
			do{
				getsym();
				i=(sym==ident) ? pl->biaoge->Position(pl->cifa->id):0;
				if (i==0)
					err->Add(35);
				else
				{
					dm->Gen(opr,0,16);
					dm->Gen(sto,lev-table[i].level,table[i].adr);
				}
				getsym();
			}while (sym==comma);

		if (sym!=rparen)
		{
			err->Add(33);
			while (fsys.InSet(sym)) getsym();
		}
		else getsym();
		break;
	case writesym:
		s=fsys;
		s+=rparen;
		s+=comma;
		getsym();
		if (sym==lparen)
		{
			do{
				getsym();
				expression(s);
				pl->daima->Gen(opr,0,14);
			}while (sym==comma);
			if (sym!=rparen)
				err->Add(33);
			else
				getsym();
		}
		dm->Gen(opr,0,15);
		break;
	case callsym:
		getsym();
		if (sym!=ident)
			err->Add(14);
		else
		{
			i=pl->biaoge->Position(pl->cifa->id);
			if (i==0) err->Add(11);
			else if (table[i].kind==procedure)
				dm->Gen(cal,lev-table[i].level,table[i].adr);
			else
				err->Add(15);
			getsym();
		}
		break;
	case ifsym:
		s=fsys;
		s+=thensym;
		s+=dosym;
		getsym();
		condition(s);
		if (sym==thensym) getsym();else err->Add(16);
		cx1=dm->cx;
		dm->Gen(jpc,0,0);
		s=fsys;
		s+=elsesym;
		statement(s);
		if (sym==elsesym)
		{
			getsym();
			cx2=dm->cx;
			dm->Gen(jmp,0,0);
			statement(fsys);
			dm->code[cx1].a=cx2+1;
			dm->code[cx2].a=dm->cx;
		}
		else
			dm->code[cx1].a=dm->cx;
		break;
	case beginsym:
		s=fsys;
		s+=semicolon;
		s+=endsym;
		s2=statbegsys;
		s2+=semicolon;
		getsym();
		statement(s);
		while (s2.InSet(sym))
		{
			if (sym==semicolon) getsym();else err->Add(10);
			statement(s);
		}
		if (sym==endsym) getsym(); else err->Add(17);
		break;
	case whilesym:
		cx1=dm->cx;
		getsym();
		s=fsys;
		s+=dosym;
		condition(s);
		cx2=dm->cx;
		dm->Gen(jpc,0,0);
		if (sym==dosym) getsym(); else err->Add(18);
		statement(fsys);
		dm->Gen(jmp,0,cx1);
		dm->code[cx2].a=dm->cx;
		break;
	case repeatsym:
		getsym();
		s=fsys;
		s+=semicolon;
		s+=untilsym;
		cx1=dm->cx;
		statement(s);
		s2=statbegsys;
		s2+=semicolon;
		while (s2.InSet(sym))
		{
			if (sym==semicolon) getsym();else err->Add(10);
			statement(s);
		}
		if (sym==untilsym)
		{
			getsym();
			condition(fsys);
			dm->Gen(jpc,0,cx1);
		}
		else
			err->Add(25);
		break;
	}
	test(fsys,CSymbolSet(),19);
}

⌨️ 快捷键说明

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