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

📄 compile.cpp

📁 编译原理课程设计大作业PL0文法简易编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				else
					ttab[*t].fields = namelist[lev];
				lev = lev - 1;
				skip(endsym);
			}
		}
	}
}

/*类型声明,type保留字处*/
void typedeclaration()
{
	alfa a;
	int t;
	strcpy(a, id);
	getsym();
	skip(eql);
	typ(&t);
	skip(semicolon);
	enter(a, tipe, t);
}

/*变量声明*/
void vardeclaration()
{
	int p, q, t;
	enter(id, varbl, 0);
	p = ix;
	getsym();
	while(sym == comma)
	{
		getsym();
		check(ident);
		enter(id, varbl, 0);
		getsym();
	}
	q = ix;
	skip(colon);
	typ(&t);
	skip(semicolon);
	do{
		itab[p].vlevel = lev;
		dx = dx - ttab[t].size;
		itab[p].tip = t;
		itab[p].vadr = dx;
		itab[p].refpar = FALSE;
		p = p + 1;
	}while(p <= q); 
}

/*参数列表*/
void paramlist(int *p, int * ps)
{
	BOOL r;
	int t;
	if(sym == varsym)
	{
		r = TRUE;
		getsym();
	}
	else
		r = FALSE;
	check(ident);
	*p = ix;
	enter(id, varbl, 0);
	getsym();
	while(sym == comma)
	{
		getsym();
		check(ident);
		enter(id, varbl, 0);
		getsym();
	}
	skip(colon);
	check(ident);
	typ(&t);
	while(*p < ix)
	{
		*p = *p + 1;
		itab[*p].tip = t;
		itab[*p].refpar = r;
		if(r)
			*ps = *ps + 1; /*传地址*/
		else
			*ps = *ps + ttab[t].size; /*传值*/
	}
}

void funcdeclaration(BOOL isf)
{
	int f, p, ps, odx;
	getsym();
	check(ident);
	enter(id, funkt, 0);
	getsym();
	f = ix;
	itab[f].flevel = lev;
	itab[f].fadr = codelabel();
	gen1(jump, 0);
	if(lev == lmax)
	{
		error(127); /*深度超过限度,应退出*/
	}
	lev = lev + 1;
	if(lev == -1)
		nl = 0;
	else
		namelist[lev] = 0;
	ps = 1;
	odx = dx;
	if(sym == lparen)
	{
		do{
			getsym();
			paramlist(&p, &ps);
		}while(sym == semicolon);
		skip(rparen);
	}
	if(lev > 1)
		dx = -1;
	else
		dx = 0;
	itab[f].resultadr = ps;
	p = f;
	while(p < ix)
	{
		p = p + 1;
		if(itab[p].refpar)
			ps = ps - 1;
		else
			ps = ps - ttab[itab[p].tip].size;
		itab[p].vlevel = lev;
		itab[p].vadr = ps;
	}
	if(isf == TRUE)
	{
		skip(colon);
		check(ident);
		typ(&(itab[f].tip));
		if(ttab[itab[f].tip].kind != simple)
			error(128); /*只能返回简单类型*/
	}
	skip(semicolon);
	itab[f].lastpar = ix;
	itab[f].inside = TRUE;
	block(itab[f].fadr);
	itab[f].inside = FALSE;
	gen1(pexit, itab[f].resultadr - dx);
	lev = lev - 1;
	dx = odx;
	skip(semicolon);
}

void block(int l)
{
	int d, odx, oix;
	odx = dx;
	oix = ix;
	if(sym == constsym)
	{
		getsym();
		check(ident);
		do{
			constdeclaration();
		}while(sym == ident);
	}
	if(sym == typesym)
	{
		getsym();
		check(ident);
		do{
			typedeclaration();
		}while(sym == ident);
	}
	if(sym == varsym)
	{
		getsym();
		check(ident);
		do{
			vardeclaration();
		}while(sym == ident);
	}
	while(sym == funcsym || sym == procsym)
	{
		if(sym == funcsym)
			funcdeclaration(TRUE);
		else
			funcdeclaration(FALSE);
	}
	if(l + 1 == codelabel())
		cx = cx -1;
	else
		code[l].a = codelabel();
	if(lev == 0)
		gen1(sets, dx);
	else
	{
		d = dx - odx;
		dx = odx;
		gen1(adjs, d);
	}
	statement();
	if(lev != 0)
		gen1(adjs, odx - dx);
	ix = oix;
}

void listcode(FILE * fi)
{
	int i;
	for(i = 0; i < cx; i++)
	{
		fprintf(fi, "%-4d :   ", i);
		switch(code[i].op)
		{
		case add:
			fprintf(fi, "add\n");
			break;
        case neg:
			fprintf(fi, "neg\n");
			break;
		case inc:
			fprintf(fi, "inc\n");
			break;
		case dec:
			fprintf(fi, "dec\n");
			break;
        case mul:
			fprintf(fi, "mul\n");
			break;
        case divd:
			fprintf(fi, "divd\n");
			break;
        case remd:
			fprintf(fi, "remd\n");
			break;
        case div2:
			fprintf(fi, "div2\n");
			break;
        case rem2:
			fprintf(fi, "rem2\n");
			break;
        case eqli:
			fprintf(fi, "eqli\n");
			break;
        case neqi:
			fprintf(fi, "neqi\n");
			break;
        case lssi:
			fprintf(fi, "lssi\n");
			break;
        case leqi:
			fprintf(fi, "leqi\n");
			break;
        case gtri:
			fprintf(fi, "gtri\n");
			break;
        case geqi:
			fprintf(fi, "geqi\n");
			break;
        case dupl:
			fprintf(fi, "dupl\n");
			break;
        case swap:
			fprintf(fi, "swap\n");
			break;
        case andb:
			fprintf(fi, "andb\n");
			break;
        case orb:
			fprintf(fi, "orb\n");
			break;
        case load:
			fprintf(fi, "load\n");
			break;
        case stor:
			fprintf(fi, "stor\n");
			break;
        case hhalt:
			fprintf(fi, "hhalt\n");
			break;
        case wri:
			fprintf(fi, "wri\n");
			break;
        case wrc:
			fprintf(fi, "wrc\n");
			break;
        case wrl:
			fprintf(fi, "wrl\n");
			break;
        case rdi:
			fprintf(fi, "rdi\n");
			break;
        case rdc:
			fprintf(fi, "rdc\n");
			break;
        case rdl:
			fprintf(fi, "rdl\n");
			break;
        case eol:
			fprintf(fi, "eol\n");
			break;
        case ldc:
			fprintf(fi, "ldc   %d\n", code[i].a);
			break;
        case ldla:
			fprintf(fi, "ldla  %d\n", code[i].a);
			break;
        case ldl:
			fprintf(fi,"ldl   %d\n", code[i].a);
			break;
        case ldg:
			fprintf(fi, "ldg   %d\n", code[i].a);
			break;
        case stl:
			fprintf(fi, "stl   %d\n", code[i].a);
			break;
        case stg:
			fprintf(fi, "stg   %d\n", code[i].a);
			break;
        case move:
			fprintf(fi, "move  %d\n", code[i].a);
			break;
        case copy:
			fprintf(fi, "copy  %d\n", code[i].a);
			break;
        case addc:
			fprintf(fi, "addc  %d\n", code[i].a);
			break;
        case mulc:
			fprintf(fi, "mulc  %d\n", code[i].a);
			break;
        case jump:
			fprintf(fi, "jump  %d\n", code[i].a);
			break;
        case jumpz:
			fprintf(fi, "jumpz %d\n", code[i].a);
			break;
        case call:
			fprintf(fi, "call  %d\n", code[i].a);
			break;
        case adjs:
			fprintf(fi, "adjs  %d\n", code[i].a);
			break;
        case sets:
			fprintf(fi, "sets  %d\n", code[i].a);
			break;
        case pexit:
			fprintf(fi, "exit  %d\n", code[i].a);
			break;
  }
 }
}

void compile()
{
	ttab[intip].size = 1;
	ttab[intip].kind = simple;
	ttab[chartip].size = 1;
	ttab[chartip].kind = simple;
	ttab[booltip].size = 1;
	ttab[booltip].kind = simple;
	tx = 3;
	nl = 0; /* namelist[-1] = 0; */
	lev = -1;
	ix = 0;
	enter("false", konst, booltip);
	itab[ix].val = FALSE;
	enter("true", konst, booltip);
	itab[ix].val = TRUE;
	enter("maxint", konst, intip);
	itab[ix].val = 32767;
	enter("integer", tipe, intip);
	enter("char", tipe, chartip);
	enter("boolean", tipe, booltip);
	
	enter("abs", funkt, intip);
	itab[ix].flevel = -1;
	itab[ix].fadr = fabs;
	itab[ix].inside = FALSE;
	
	enter("sqr", funkt, intip);
	itab[ix].flevel = -1;
	itab[ix].fadr = fsqr;
	itab[ix].inside = FALSE;
	
	enter("odd", funkt, booltip);
	itab[ix].flevel = -1;
	itab[ix].fadr = fodd;
	itab[ix].inside = FALSE;
	
	enter("chr", funkt, chartip);
	itab[ix].flevel = -1;
	itab[ix].fadr = fchr;
	itab[ix].inside = FALSE;
	
	enter("ord", funkt, intip);
	itab[ix].flevel = -1;
	itab[ix].fadr = ford;
	itab[ix].inside = FALSE;
	
	enter("write", funkt, 0);
	itab[ix].flevel = -1;
	itab[ix].fadr = fwrite;
	
	enter("writeln", funkt, 0);
	itab[ix].flevel = -1;
	itab[ix].fadr = fwriteln;
	
	enter("read", funkt, 0);
	itab[ix].flevel = -1;
	itab[ix].fadr = fread;
	
	enter("readln", funkt, 0);
	itab[ix].flevel = -1;
	itab[ix].fadr = freadln;
	
	enter("eoln", funkt, booltip);
	itab[ix].flevel = -1;
	itab[ix].fadr = feoln;
	itab[ix].inside = FALSE;
	
	namelist[0] = 0;
	lev = 0;
	cc = 0;
	ll = 0;
	
	getch();
	getsym();
	
	labeled = FALSE;
	cx = 0;
	dx = amax + 1;
	
	block(0);
	gen0(hhalt);
	check(period);
}

/*解释执行*/
void interpret()
{
	int pc, sp, j, k, n;
	instr i;
	char c;
	BOOL h;
	
	pc = 0;
	h = FALSE;
	do{
		i = code[pc];
		pc = pc + 1;
		switch(i.op)
		{
		case add:
			m[sp + 1] = m[sp + 1] + m[sp];
			sp = sp + 1;
			break;
		case inc:
			m[sp] = m[sp] + 1;
			break;
		case dec:
			m[sp] = m[sp] - 1;
			break;
		case neg:
			m[sp] = -m[sp];
			break;
		case mul:
			m[sp + 1] = m[sp + 1] * m[sp];
			sp = sp + 1;
			break;
		case divd:
			m[sp + 1] = m[sp + 1] / m[sp];
			sp = sp + 1;
			break;
		case remd:
			m[sp + 1] = m[sp + 1] % m[sp];
			sp = sp + 1;
			break;
		case div2:
			m[sp] = m[sp] / 2;
			break;
		case rem2:
			m[sp] = m[sp] % 2;
			break;
		case eqli:
			m[sp + 1] = (m[sp + 1] == m[sp]);
			sp = sp + 1;
			break;
		case neqi:
			m[sp + 1] = (m[sp + 1] != m[sp]);
			sp = sp + 1;
			break;
		case lssi:
			m[sp + 1] = (m[sp + 1] < m[sp]);
			sp = sp + 1;
			break;
		case leqi:
			m[sp + 1] = (m[sp + 1] <= m[sp]);
			sp = sp + 1;
			break;
		case gtri:
			m[sp + 1] = (m[sp + 1] > m[sp]);
			sp = sp + 1;
			break;
		case geqi:
			m[sp + 1] = (m[sp + 1] >= m[sp]);
			sp = sp + 1;
			break;
		case dupl:
			sp = sp - 1;
			m[sp] = m[sp + 1];
			break;
		case swap:
			k = m[sp];
			m[sp] = m[sp + 1];
			m[sp + 1] = k;
			break;
		case andb:
			if(m[sp] == 0)
				m[sp + 1] = 0;
			sp = sp + 1;
			break;
		case orb:
			if(m[sp] == 1)
				m[sp + 1] = 1;
			sp = sp + 1;
			break;
		case load:
			m[sp] = m[m[sp]];
			break;
		case stor:
			m[m[sp]] = m[sp + 1];
			sp = sp + 2;
			break;
		case hhalt:
			h = TRUE;
			break;
		case wri:
			/*待定*/
			fprintf(stdout, "%d", m[sp + 1]);
			sp = sp + 2;
			break;
		case wrc:
			fprintf(stdout, "%c", m[sp]);
			sp = sp + 1;
			break;
		case wrl:
			fprintf(stdout, "\n");
			break;
		case rdi:
			fprintf(stdout, "input integer: ");
			fscanf(stdin, "%d", &(m[m[sp]]));
			sp = sp + 1;
			break;
		case rdc:
			fprintf(stdout, "input character: ");
			fscanf(stdin, "%c", &c);
			m[m[sp]] = c;
			sp = sp + 1;
			break;
		case rdl:
			/*待定*/
			break;
		case eol:
			sp = sp - 1;
			m[sp] = feof(stdin);
			break;
		case ldc:
			sp = sp - 1;
			m[sp] = i.a;
			break;
		case ldla:
			sp = sp - 1;
			m[sp] = sp + 1 + i.a;
			break;
		case ldl:
			sp = sp - 1;
			m[sp] = m[sp + 1 + i.a];
			break;
		case ldg:
			sp = sp - 1;
			m[sp] = m[i.a];
			break;
		case stl:
			m[sp + i.a] = m[sp];
			sp = sp + 1;
			break;
		case stg:
			m[i.a] = m[sp];
			sp = sp + 1;
			break;
		case move:
			k = m[sp];
			j = m[sp + 1];
			sp = sp + 2;
			n = i.a;
			do{
				n = n - 1;
				m[k + n] = m[j + n];
			}while(n > 0);
			break;
		case copy:
			j = m[sp];
			n = i.a;
			sp = sp - n + 1;
			do{
				n = n - 1;
				m[sp + n] = m[j + n];
			}while(n > 0);
			break;
		case addc:
			m[sp] = m[sp] + i.a;
			break;
		case mulc:
			m[sp] = m[sp] * i.a;
			break;
		case jump:
			pc = i.a;
			break;
		case jumpz:
			if(m[sp] == 0)
				pc = i.a;
			sp = sp + 1;
			break;
		case call:
			sp = sp - 1;
			m[sp] = pc;
			pc = i.a;
			break;
		case adjs:
			sp = sp + i.a;
			break;
		case sets:
			sp = i.a;
			break;
		case pexit:
			pc = m[sp];
			sp = sp + i.a;
			break;
  }
 }while(h == FALSE);
}


void main(int argc, char **argv)
{
	char filename[81], save;
	FILE * sf;
	memset(filename, 0, 81);
	if(argc == 1)
	{
		fprintf(stdout, "please enter source file name: ");
		fscanf(stdin, "%s", filename);
//		strcpy(filename, "test_rabbit.PL0");
	}
	else
		strcpy(filename, argv[1]);
	source = fopen(filename, "r");
	if(source == NULL)
	{
		fprintf(stderr, "cann't open file: %s\n", filename);
		return;
	}
	fprintf(stdout, "compiling...\n");
	compile();
	fclose(source);
	fprintf(stdout, "no errors, compile succeed.\n");
	fprintf(stdout, "--------------------------------\n");
	listcode(stdout);
	fprintf(stdout, "--------------------------------\n");
	fprintf(stdout, "Run>\n");
	interpret();
	fprintf(stdout, "program exit.\n");
	fprintf(stdout, "do you want to save the code(y or n): ");
	do{
		scanf("%c", &save);
	}while(save != 'y' && save != 'Y' && save != 'n' && save != 'N');
	if(save == 'y' || save == 'Y')
	{
		fprintf(stdout, "enter file name: ");
		scanf("%s", filename);
		sf = fopen(filename, "w");
		if(sf)
		{
			listcode(sf);
			fclose(sf);
		}
		else
			fprintf(stdout, "open file error, code not saved.\n");
	}
	
}

⌨️ 快捷键说明

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