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

📄 pl0complier.cpp

📁 min_Pascal语言的语法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <set>
#include <string>
#include <iostream>
#include <iostream>
#include <vector>


#define WIRTH_ZYC_
using namespace std;

const int norw=13;
const int txmax=100;
const int al=10;
const int nmax=14;
const int amax=2047;
const int levmax=3;
const int cxmax=20000;
const int lineLength=82;
typedef enum {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} symbol;
typedef char alfa[al+1];
typedef enum{CONSTANT,VARIABLE,PROCEDURE}obj0;
typedef enum {LIT,OPR,LOD,STO,CAL,INT,JMP,JPC} fct;
typedef set<symbol> symset;

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

typedef struct{
	alfa name;
	obj0 kind;
	union {
		struct{int level,adr,size;}inOther;
		int val;
	}other;
} Table;

	void SaveCode();
	void listcode(int cx0);
	void error(int n);
	void getsym();
	void getch();
	void gen(fct x,int y,int z);
	void test(symset s1,symset s2,int n);
	void block(int lev,int tx,symset fsys);
	void enter(obj0 k,int &tx,int &dx,int lev);
	int position(alfa id,int tx);
	void constdeclaration(int&tx,int&dx,int lev);
	void vardeclaration(int&tx,int&dx,int lev);
	void factor(symset fsys,int tx,int lev);
	void term(symset fsys,int tx,int lev);
	void expression(symset fsys,int tx,int lev);
	void condition(symset fsys,int tx,int lev);
	void statement(symset fsys,int tx,int lev);
	int base(int l,int b,int s[]);
	void interpret();

	bool listswitch,sourceEnd;
	char ch;
	symbol  sym;
	alfa  id;  
	int  num;
	int  cc; 
	int  ll; 
	int  kk,err;
	int  cx; 
	int codeNo;
	char  line[lineLength];
	vector<string> errorString;
	alfa  a;
	instruction  code[cxmax+1];
	alfa  word[norw+1];
	symbol  wsym[norw+1];
	symbol ssym[100];
	char  mnemonic[8][6];
	symset  declbegsys,statbegsys,facbegsys;
	Table table[txmax+1];
	FILE*  fin,*fout;

string  errStr[]={" ",
	"error 0001:  write =  as  := ",					"error 0019:  need a num after = ",
	"error 0002:  lose = after identifier",				"error 0020:  need a identifier after const,var,procedure ",
	"error 0003:  lose , or ; ",						"error 0021:  error symbol",
	"error 0004:  error symbol",						"error 0022:  error symbol",
	"error 0005:  lose . ",								"error 0023:  lose ; ",
	"error 0006:  undeclar identifier ",				"error 0024:  must be defined as variable",
	"error 0007:  the symbol must be :=",				"error 0025:  need an identifier after call ",
	"error 0008:  call's property should be process",	"error 0026:  be lack for then",
	"error 0009:  need end or ;",						"error 0027:  need while",
	"error 0010:  uncorect identifier",					"error 0028:  it shuold be operator",
	"error 0011:  shuold not be process",				"error 0029:  lose ) ",
	"error 0012:  unreferenced identifier",				"error 0030:  can not be this identifier",
	"error 0013:  wrong end ",							"error 0031:  shuod not end here ",
	"error 0014:  ","error 0015:  ","error 0016:  ","error 0017:  ",
	"error 0018:  over flow",							"error 0032:  err read "
};
void  error(int n)
{
	char s[10];
	sprintf(s,"第 %d 行出错:",codeNo);
	errorString.push_back(s+errStr[n]);
	err= err+1;//error count
}


void  getch()
{
	if(cc==ll)
	{
		if(feof(fin))
		{
			if(sym!=PERIOD)
				error(25);
			sourceEnd=true;
			return;
		}
		cc= 0;
		fgets(line,lineLength,fin);
		codeNo++;
		ll=strlen(line);
		if(line[ll-1]==10)ll--;
	}
	ch= line[cc];
	cc= cc+1;
}
void  getsym()
{
	if(sourceEnd)
		return;
	int i,j,k;
	while (ch ==' '||ch==9)
		getch();
	if(isalpha(ch))
	{
		k=0;
		memset(a,0,al+1);
		do{
			if (k < al)
			{
				a[k]= ch;
				k= k+1;
			}
			getch();
			if(sourceEnd)
				return;
		}while(isalpha(ch)||isdigit(ch));
		if(k >= kk)
			kk= k;
		else
		{
			do{
				a[kk]= ' ';
				kk= kk-1;
			}while(kk > k);
		}
		strcpy(id,a);
		i= 1;
		j= norw;
		do{
			k= (i+j) / 2;
			if(strcmp(id, word[k])<=0)
				j= k-1;
			if(strcmp(id,word[k])>=0)
				i= k+1;
		}while(i<=j);
		if(i-1 > j)
			sym= wsym[k];
		else
			sym= IDENT;
	}
	else if(isdigit(ch))
	{
		k= 0;
		num= 0;
		sym= NUMBER;
		do{
			num= 10 * num+ch-'0';
			k= k+1;
			getch();
		}while(isdigit(ch));
		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 if(ch=='>')
		{
			sym=NEQ;
			getch();
		}
		else
			sym= LSS;
	}
	else if (ch == '>')
	{
		getch();
		if( ch == '=')
		{
			sym= GEQ;
			getch();
		}
		else
			sym= GTR;
	}
	else
	{
		sym= ssym[ch];
		getch();
	}
}

void  gen(fct x,int y,int z)
{
	if (cx > cxmax)
	{
		cout<<"Program too long\n";
		return;
	}
	code[cx].f= x;
	code[cx].l= y;
	code[cx].a= z;
    cx= cx+1;
}

void  test(symset s1,symset s2,int n)
{
	if(sourceEnd)return;
	if (s1.find(sym)==s1.end())
	{
		error(n);
		symset::iterator it;
		for(it=s2.begin();it!=s2.end();it++)
			s1.insert(*it);
		while (s1.find(sym)==s1.end())
			getsym();
	}
}
void  enter(obj0 k,int &tx,int &dx,int lev)
{
	tx= tx+1;
	strcpy(table[tx].name,id);
	table[tx].kind=k;
	switch(k)
	{
	case CONSTANT:
		if(num>amax)
		{
			error(31);
			num=0;
		}
		table[tx].other.val=num;
		break;
	case VARIABLE:
		table[tx].other.inOther.level=lev;
		table[tx].other.inOther.adr=dx;
		dx++;
		break;
	case PROCEDURE:
		table[tx].other.inOther.level=lev;
		break;
	}
}

int  position(alfa id,int tx)
{
	int i;
	strcpy(table[0].name, id);
	i= tx;
	while (strcmp(table[i].name,id)!=0)i--;
	return i;
}
void  constdeclaration(int&tx,int&dx,int lev)
{
	if(sym = IDENT)
	{
	  getsym();
	  if(sym>=EQL&&sym<=BECOMES)
	  {
		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++)
		   cout<<" "<<i<<"  "<<mnemonic[code[i].f]
			<<"  "<<code[i].l<<"  "<<code[i].a<<endl;
}
void   factor(symset fsys,int tx,int lev)
{
	int i;
	test(facbegsys,fsys,24);
	while(facbegsys.find(sym)!=facbegsys.end())
	{
		if( sym ==IDENT)
		{
			i= position(id,tx);
			if( i == 0)
				error(11);
			else
				switch(table[i].kind)
			{
			 case CONSTANT:
				 gen(LIT,0,table[i].other.val);
				 break;
			 case VARIABLE:
				 gen(LOD,lev-table[i].other.inOther.level,table[i].other.inOther.adr);
				 break;
			 case PROCEDURE:
				 error(21);
				 break;
			}
			getsym();
		}
		else  if (sym ==NUMBER)
		{
			if (num>amax)
			{
				error(31);
				num= 0;
			}
			gen(LIT,0,num);
			getsym();
		}
		else if( sym ==LPAREN)
		{
			getsym();
			symset tmp=fsys;
			tmp.insert(RPAREN);
			expression(tmp,tx,lev);
			if (sym == RPAREN)
				getsym();
			else
				error(22);
		}
		test(fsys,facbegsys,23);
	}
}
void  term(symset fsys,int tx,int lev)
{
	if(sourceEnd)
		return;
	symbol  mulop;
	symset tmp=fsys;
	for(int t=TIMES;t<=SLASH;t++)
		tmp.insert((symbol)t);
	factor(tmp,tx,lev);
	while( sym>=TIMES && sym<=SLASH)
	{
		mulop= sym;
		getsym();
		factor(tmp,tx,lev);
		if (mulop ==TIMES)
			gen(OPR,0,4);
		else
			gen(OPR,0,5);
	}
}
void  expression(symset fsys,int tx,int lev)
{
	symbol addop;
	symset tmp=fsys;
	for(int t=PLUS;t<=MINUS;t++)
		tmp.insert((symbol)t);
	if( sym>=PLUS&&sym<=MINUS)
	{
		addop= sym;
		getsym();
		term(tmp,tx,lev);
		if( addop ==MINUS)
			gen(OPR,0,1);
	}
	else
		term(tmp,tx,lev);
	while (sym >=PLUS&&sym<=MINUS)
	{
		addop= sym;
		getsym();
		term(tmp,tx,lev);
		if (addop ==PLUS)
			gen(OPR,0,2);
		else
			gen(OPR,0,3);
	}
}
void  condition(symset fsys,int tx,int lev)
{
	symbol relop;
	symset tmp=fsys;
	tmp.insert(EQL),tmp.insert(NEQ),tmp.insert(LSS),tmp.insert(LEQ),tmp.insert(GTR),tmp.insert(GEQ);
    if( sym ==ODDSYM)
	{
		getsym();
		expression(fsys,tx,lev);
		gen(OPR,0,6);
	}
	else
	{
		expression(tmp,tx,lev);
		if(tmp.find(sym)==tmp.end())
			error(20);
		else
		{
			relop= sym;
			getsym();
			expression(fsys,tx,lev);
			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  statement(symset fsys,int tx,int lev)
{
	if(sourceEnd)
		return;
	int i,cx1,cx2;
	if(sym ==IDENT)
	{
		i= position(id,tx);
		if (i == 0)
			error(11);
		else if (table[i].kind!=VARIABLE)
		{

⌨️ 快捷键说明

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