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

📄 interpreter.cpp

📁 C0文法编译器
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Com_def.h"


#define DTOP				10000		// 数据栈栈顶值
#define CMAX                15          // 指令集中最长的指令长度
#define CNO					25			// 指令集中指令的个数
struct sc{
	int type;							// 表示v中数据的类型
	struct{						
		int ival;
		float fval;
	} v;
};

sc data[DTOP];							// 数据栈,只存放数据对象的指针(引用)
int dptr;								// 数据栈指针
int abp;								// 活动记录的基地址
int preabp;								// 调用活动记录的基地址
char c;									// 用于WRITES语句,打印字符串

sc run[DTOP];							// 运行栈
int rptr;								// 运行栈栈顶指针

FILE *fp;								// 文件指针

const char code[CNO][CMAX]={"ALLOCATE","STO","LOAD","LOADI","POP","JSR","RETURN",
							"ADD","SUB","MULT","DIV","EQ","NOTEQ","GT","LES","GE",
							"LE","BRF","BR","WRITEI","WRITES","CONVER","READ","WRITEF","WRITEC"};

int Locate(char s[]){						// 分析指令,并返回指令代号						
	int i;
	for (i=0;i<CNO;i++)
		if (strcmp(code[i],s)==0)
			return i;
	return -1;
}

int LocLabel(char s[]){						// 定位标号,返回标号所在的位置	
	char lab[255];
	strcat(s,":");
	fseek(fp,0,SEEK_SET);
	fscanf(fp,"%s",lab);
	while (strcmp(s,lab)!=0)
		fscanf(fp,"%s",lab);
	return 1;
}

int getAdd(int &ll,int &on,char s[]){		// 将地址解析为层号和偏移值
	int i=0;
	ll=on=0;
	while (s[++i]!=','){
		ll=ll*10+(s[i]-'0');
	}
	while (s[++i]!='>'){
		on=on*10+(s[i]-'0');
	}
	return 1;
}

int Cal(int t){								// 解析ADD,SUB,MULT,DIV, t为操作的类型
	int t1,t2;
	float f1,f2;
	bool flag=true;
	if (data[dptr-1].type==REAL && data[dptr-2].type==REAL){
		f1=data[--dptr].v.fval;
		f2=data[--dptr].v.fval;
		switch(t){
		case 1:f1+=f2; break;
		case 2:f1=f2-f1; break;
		case 3:f1*=f2; break;
		case 4:f1=f2/f1; break;
		}
		data[dptr].type=REAL;
		data[dptr++].v.fval=f1;
	}
	else if (data[dptr-1].type==INTEGER && data[dptr-2].type==INTEGER){
		t1=data[--dptr].v.ival;
		t2=data[--dptr].v.ival;
		switch(t){
		case 1:t1+=t2; break;
		case 2:t1=t2-t1; break;
		case 3:t1*=t2; break;
		case 4:									// 两个整数相除时,可能产生浮点数
			if (t2%t1==0)
				t1=(int)t2/t1; 
			else{
				f1=(float)t2/t1;
				flag=false;
			}
			break;
		}
		if (flag){
			data[dptr].type=INTEGER;
			data[dptr].v.ival=t1;
			data[dptr++].v.fval=(float)f1;
		}
		else{
			data[dptr].type=REAL;
			data[dptr++].v.fval=f1;
		}
	}
	else if (data[dptr-1].type==REAL && data[dptr-2].type==INTEGER){
		f1=data[--dptr].v.fval;
		t1=data[--dptr].v.ival;
		switch(t){
		case 1:f1+=t1; break;
		case 2:f1=t1-f1; break;
		case 3:f1*=t1; break;
		case 4:f1=t1/f1; break;
		}
		data[dptr].type=REAL;
		data[dptr++].v.fval=f1;
	}
	else if (data[dptr-1].type==INTEGER && data[dptr-2].type==REAL){
		t1=data[--dptr].v.ival;
		f1=data[--dptr].v.fval;
		switch(t){
		case 1:f1+=t1; break;
		case 2:f1=f1-t1; break;
		case 3:f1*=t1; break;
		case 4:f1=f1/t1; break;
		}
		data[dptr].type=REAL;
		data[dptr++].v.fval=f1;
	}
	return 1;
}

int GetData(float f[],int t[],int &type){
	int i,temp;
	char s[2];
	for (i=0;i<2;i++){
		temp=data[--dptr].type;
		if (temp==INTEGER){
			s[i]='1';
			t[i]=data[dptr].v.ival;
		}
		else{
			f[i]=data[dptr].v.fval;
			s[i]='2';
		}
	}
	type=atoi(s);
	return 1;
}

void Interpreter(char *fileName){			// 解释执行
	fp=fopen(fileName,"r");
	dptr=0; abp=1; rptr=4; preabp=-1;
	char s[15];	
	int i,temp,ll,on,tp,type;
	float f[2];
	int t[2];
	while(!feof(fp)){
		do{
			fscanf(fp,"%s",s);
		}while (s[strlen(s)-1]==':');
		tp=Locate(s);
		switch(tp){
		case 0:								// 处理ALLOCATE语句
			fscanf(fp,"%d",&i);
			rptr+=i;
			break;
		case 1:								// 处理STO语句
			fscanf(fp,"%s",s);
			getAdd(ll,on,s);
			if (ll==0)						// 判断是全局变量还是本层的变量
				run[on-1]=data[--dptr];
			else
				run[abp+on-1]=data[--dptr];
			break;
		case 2:								// 处理LOAD语句		
			fscanf(fp,"%s",s);
			if (strcmp(s,"$Top")!=0){
				getAdd(ll,on,s);
				if (ll==0)
					if (run[on-1].type==REAL || run[on-1].type==INTEGER)		// 防止对没有进行初始化的变量的引用
						data[dptr++]=run[on-1];
					else
						data[dptr++].type=2;
				else
					if (run[abp+on-1].type==REAL || run[abp+on-1].type==INTEGER)	// 防止对没有进行初始化的变量的引用
						data[dptr++]=run[abp+on-1];
					else
						data[dptr++].type=2;
			}
			else{
				data[dptr]=data[dptr-1];
				dptr++;
			}
			break;
		case 3:								// 处理LOADI语句
			fscanf(fp,"%s",s);
			if (strchr(s,'.')==NULL){
				data[dptr].type=INTEGER;
				data[dptr].v.ival=atoi(s);
				data[dptr++].v.fval=(float)(atof(s));
			}
			else{
				data[dptr].type=REAL;
				data[dptr++].v.fval=(float)atof(s);
			}
			break;
		case 4:								// 处理POP语句
			dptr--;
			break;
		case 5:								// 处理JSR语句
			fscanf(fp,"%s",s);
			LocLabel(s);
			run[rptr+2].type=INTEGER;			// 分配活动记录,设置abp,preabp
			run[rptr+2].v.ival=abp;
			abp=rptr;
			rptr=rptr+3;
			break;	
		case 6:								// 处理RETURN语句
			temp=run[abp].v.ival;				// 取返回地址
			itoa(temp,s,10);
			if (temp!=-1){						// -1为主程序活动记录的调用基地址
				LocLabel(s);
				temp=abp;
				abp=run[abp+2].v.ival;				// 消除活动记录 abp=preabp;
				rptr=temp;
			}
			break;
		case 7: Cal(1); break;					// 处理ADD语句
		case 8: Cal(2); break;					// 处理SUB语句
		case 9: Cal(3); break;					// 处理MULT语句
		case 10:Cal(4); break;					// 处理DIV语句
		case 11:								// 处理EQ语句
			GetData(f,t,type);
			data[dptr].type=INTEGER;	
			if ((type==11 && t[1]==t[0]) || (type==22 && f[1]==f[0])
				|| (type==12 && f[1]==t[0]) || (type==21 && t[1]==f[0]))
					data[dptr++].v.ival=1;
			else
					data[dptr++].v.ival=0;
			break;
		case 12:								// 处理NEQ语句
			GetData(f,t,type);
			data[dptr].type=INTEGER;
			if ((type==11 && t[1]!=t[0]) || (type==22 && f[1]!=f[0])
				|| (type==12 && f[1]!=t[0]) || (type==21 && t[1]!=f[0]))
					data[dptr++].v.ival=1;
			else
					data[dptr++].v.ival=0;
			break;
		case 13:								// 处理GT语句
			GetData(f,t,type);
			data[dptr].type=INTEGER;
			if ((type==11 && t[1]>t[0]) || (type==22 && f[1]>f[0])
				|| (type==12 && f[1]>t[0]) || (type==21 && t[1]>f[0]))
					data[dptr++].v.ival=1;
			else
					data[dptr++].v.ival=0;
			break;
		case 14:								// 处理LES语句
			GetData(f,t,type);
			data[dptr].type=INTEGER;
			if ((type==11 && t[1]<t[0]) || (type==22 && f[1]<f[0])
				|| (type==12 && f[1]<t[0]) || (type==21 && t[1]<f[0]))
					data[dptr++].v.ival=1;
			else
					data[dptr++].v.ival=0;
			break;
		case 15:								// 处理GE语句
			GetData(f,t,type);
			data[dptr].type=INTEGER;
			if ((type==11 && t[1]>=t[0]) || (type==22 && f[1]>=f[0])
				|| (type==12 && f[1]>=t[0]) || (type==21 && t[1]>=f[0]))
					data[dptr++].v.ival=1;
			else
					data[dptr++].v.ival=0;
			break;
		case 16:								// 处理LE语句
			GetData(f,t,type);
			data[dptr].type=INTEGER;
			if ((type==11 && t[1]<=t[0]) || (type==22 && f[1]<=f[0])
				|| (type==12 && f[1]<=t[0]) || (type==21 && t[1]<=f[0]))
					data[dptr++].v.ival=1;
			else
					data[dptr++].v.ival=0;
			break;
		case 17:								// 处理BRF语句
			fscanf(fp,"%s",s);
			temp=data[--dptr].v.ival;
			if (temp==0)
				LocLabel(s);
			break;
		case 18:								// 处理BR语句
			fscanf(fp,"%s",s);
			LocLabel(s);
			break;
		case 19:								// 处理WRITEI语句
			printf("%d",data[--dptr].v.ival);
			break;
		case 20:								// 处理WRITES语句
			c=fgetc(fp);
			while ((c=getc(fp))!='\n' && c!='\t'){
				if (c!='\\')
					printf("%c",c);
				else{
					c=getc(fp);
					if (c=='\n' && c!='\t')
						break;
					if (c=='n')
						printf("\n");
				}
			}
			break;
		case 21:								// 处理CONVER语句
			fscanf(fp,"%s",s);
			if (strcmp(s,"$top"))
				i=1;
			else 
				i=2;
			data[dptr-i].type=REAL;
			data[dptr-i].v.fval=(float)data[dptr-i].v.ival;
			break;
		case 22:								// 处理READ语句
			scanf("%s",s);
			if (s[0]>='0' && s[0]<='9'){
				if (strchr(s,'.')==NULL){
					data[dptr].type=2;
					data[dptr].v.ival=atoi(s);
					data[dptr++].v.fval=(float)atof(s);
				}
				else{
					data[dptr].type=3;
					data[dptr++].v.fval=(float)atof(s);
				}
			}
			else{
				temp=strlen(s);
				data[dptr].type=2;
				data[dptr].v.ival=s[0];
				data[dptr++].v.fval=(float)s[0];
			}
			break;
		case 23:								// 处理WRITEF语句
			printf("%f",data[--dptr].v.fval);
			break;
		case 24:
			printf("%c",data[--dptr].v.ival);	// 处理WRITEC语句
			break;
		}
	
	}
}

⌨️ 快捷键说明

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