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

📄 pl0.c

📁 pl0修改后的源程序和报告 (1) 修改后的PL/0语言文本。包含词法分析(正规式)
💻 C
📖 第 1 页 / 共 2 页
字号:
{	int i, cx1, cx2;	symset set1, set;	if (sym == SYM_IDENTIFIER)	{ // variable assignment		mask* mk;		if (! (i = position(id)))		{			error(11); // Undeclared identifier.		}		else if (table[i].kind != ID_VARIABLE)		{			error(12); // Illegal assignment.			i = 0;		}		getsym();		if (sym == SYM_BECOMES)		{			getsym();		}		else		{			error(13); // ':=' expected.		}		expression(fsys);		mk = (mask*) &table[i];		if (i)		{			gen(STO, level - mk->level, mk->address);		}	}	else if (sym == SYM_CALL)	{ // procedure call		getsym();		if (sym != SYM_IDENTIFIER)		{			error(14); // There must be an identifier to follow the 'call'.		}		else		{			if (! (i = position(id)))			{				error(11); // Undeclared identifier.			}			else if (table[i].kind == ID_PROCEDURE)			{				mask* mk;				mk = (mask*) &table[i];				gen(CAL, level - mk->level, mk->address);			}			else			{				error(15); // A constant or variable can not be called. 			}			getsym();		} // else	} 	else if (sym == SYM_IF)	{ // if statement		getsym();		set1 = createset(SYM_THEN, SYM_DO, SYM_NULL);		set = uniteset(set1, fsys);		condition(set);		destroyset(set1);		destroyset(set);		if (sym == SYM_THEN)		{			getsym();		}		else		{			error(16); // 'then' expected.		}		cx1 = cx;		gen(JPC, 0, 0);		statement(fsys);		code[cx1].a = cx;		}	else if (sym == SYM_BEGIN)	{ // block		getsym();		set1 = createset(SYM_SEMICOLON, SYM_END, SYM_NULL);		set = uniteset(set1, fsys);		statement(set);		while (sym == SYM_SEMICOLON || inset(sym, statbegsys))		{			if (sym == SYM_SEMICOLON)			{				getsym();			}			else			{				error(10);			}			statement(set);		} // while		destroyset(set1);		destroyset(set);		if (sym == SYM_END)		{			getsym();		}		else		{			error(17); // ';' or 'end' expected.		}	}	else if (sym == SYM_WHILE)	{ // while statement		cx1 = cx;		getsym();		set1 = createset(SYM_DO, SYM_NULL);		set = uniteset(set1, fsys);		condition(set);		destroyset(set1);		destroyset(set);		cx2 = cx;		gen(JPC, 0, 0);		if (sym == SYM_DO)		{			getsym();		}		else		{			error(18); // 'do' expected.		}		statement(fsys);		gen(JMP, 0, cx1);		code[cx2].a = cx;	}	else		//增加的地方		test(fsys, phi, 19);} // statement			//////////////////////////////////////////////////////////////////////void block(symset fsys){	int cx0; // initial code index	mask* mk;	int block_dx;	int savedTx;	symset set1, set;	dx = 3;	block_dx = dx;	mk = (mask*) &table[tx];	mk->address = cx;	gen(JMP, 0, 0);	if (level > MAXLEVEL)	{		error(32); // There are too many levels.	}	do	{		if (sym == SYM_CONST)		{ // constant declarations			getsym();/*			do			{	删除的地方 */				constdeclaration();				while (sym == SYM_COMMA)				{					getsym();					constdeclaration();				}				if (sym == SYM_SEMICOLON)				{					getsym();				}				else				{					error(5); // Missing ',' or ';'.				}/*			}			while (sym == SYM_IDENTIFIER);			删除的地方*/		} // if		if (sym == SYM_VAR)		{ // variable declarations			getsym();/*			do			{			删除的地方 */				vardeclaration();				while (sym == SYM_COMMA)				{					getsym();					vardeclaration();				}				if (sym == SYM_SEMICOLON)				{					getsym();				}				else				{					error(5); // Missing ',' or ';'.				}/*			}			while (sym == SYM_IDENTIFIER);			删除的地方 */			block_dx = dx;		// 修改的地方		} // if		while (sym == SYM_PROCEDURE)		{ // procedure declarations			getsym();			if (sym == SYM_IDENTIFIER)			{				enter(ID_PROCEDURE);				getsym();			}			else			{				error(4); // There must be an identifier to follow 'const', 'var', or 'procedure'.			}			if (sym == SYM_SEMICOLON)			{				getsym();			}			else			{				error(5); // Missing ',' or ';'.			}			level++;			savedTx = tx; //删除的地方			set1 = createset(SYM_SEMICOLON, SYM_NULL);			set = uniteset(set1, fsys);			block(set);			destroyset(set1);			destroyset(set);			tx = savedTx;	//删除的地方			level--;			if (sym == SYM_SEMICOLON)			{				getsym();				set1 = createset(SYM_IDENTIFIER, SYM_PROCEDURE, SYM_NULL);				set = uniteset(statbegsys, set1);				test(set, fsys, 6);				destroyset(set1);				destroyset(set);			}			else			{				error(5); // Missing ',' or ';'.			}		} // while		set1 = createset(SYM_IDENTIFIER, SYM_NULL);		set = uniteset(statbegsys, set1);		test(set, declbegsys, 7);		destroyset(set1);		destroyset(set);	}	while (inset(sym, declbegsys));	code[mk->address].a = cx;	mk->address = cx;	cx0 = cx;	gen(INT, 0, block_dx);	set1 = createset(SYM_SEMICOLON, SYM_END, SYM_NULL);	set = uniteset(set1, fsys);	statement(set);	destroyset(set1);	destroyset(set);	gen(OPR, 0, OPR_RET); // return	test(fsys, phi, 8); // test for error: Follow the statement is an incorrect symbol.	listcode(cx0, cx);} // block//////////////////////////////////////////////////////////////////////int base(int stack[], int currentLevel, int levelDiff){	int b = currentLevel;	printf("base(currentLevel=%d, levelDiff=%d)\n", currentLevel,levelDiff);#if 0	//修改的地方,测试栈是否为空	while (levelDiff--)#else	if (levelDiff>0)		while (levelDiff--)	 #endif		b = stack[b];	return b;} // base//////////////////////////////////////////////////////////////////////// interprets and executes codes.void interpret(){	int pc;        // program counter	int stack[STACKSIZE];	int top;       // top of stack	int b;         // program, base, and top-stack register	instruction i; // instruction register
//	int mm;	printf("Begin executing PL/0 program.\n");	fprintf(outfile, "Begin executing PL/0 program.\n");	pc = 0;	b = 1;	top = 0;  	stack[1] = 1;
    stack[2] = stack[3] = 0;	do	{		i = code[pc++];		switch (i.f)		{		case LIT:			stack[++top] = i.a;			break;		case OPR:			switch (i.a) // operator			{			case OPR_RET:				top = b - 1;				pc = stack[top + 3];				b = stack[top + 2];				break;			case OPR_NEG:				stack[top] = -stack[top];				break;			case OPR_ADD:				top--;				stack[top] += stack[top + 1];				break;			case OPR_MIN:				top--;				stack[top] -= stack[top + 1];				break;			case OPR_MUL:				top--;				stack[top] *= stack[top + 1];				break;			case OPR_DIV:				top--;				if (stack[top + 1] == 0)				{					fprintf(stderr, "Runtime Error: Divided by zero.\n");					fprintf(stderr, "Program terminated.\n");					continue;				}				stack[top] /= stack[top + 1];				break;			case OPR_ODD:				stack[top] %= 2;				break;			case OPR_EQU:				top--;				stack[top] = stack[top] == stack[top + 1];				break;			case OPR_NEQ:				top--;				stack[top] = stack[top] != stack[top + 1];				break;		// 增加的地方			case OPR_LES:				top--;				stack[top] = stack[top] < stack[top + 1];				break;			case OPR_GEQ:				top--;				stack[top] = stack[top] >= stack[top + 1];				break;		// 增加的地方			case OPR_GTR:				top--;				stack[top] = stack[top] > stack[top + 1];				break;			case OPR_LEQ:				top--;				stack[top] = stack[top] <= stack[top + 1];			} // switch			break;		case LOD:
			stack[++top] = stack[base(stack, b, i.l) + i.a];			break;		case STO:			stack[base(stack, b, i.l) + i.a] = stack[top];			printf("%d\n", stack[top]);			fprintf(outfile, "%d\n", stack[top]);			top--;			break;		case CAL:			stack[top + 1] = base(stack, b, i.l);			// generate new block mark			stack[top + 2] = b;			stack[top + 3] = pc;			b = top + 1;			pc = i.a;			break;		case INT:			top += i.a;			break;		case JMP:			pc = i.a;			break;		case JPC:			if (stack[top] == 0)				pc = i.a;			top--;			break;		} // switch	}	while (pc);	//printf("End executing PL/0 program.\n");	fprintf(outfile, "End executing PL/0 program.\n");} // interpret//////////////////////////////////////////////////////////////////////void main (){	FILE* hbin;	char s[80],*finddot;	int i;	symset set, set1, set2;	printf("Please input source file name: "); // get file name to be compiled//	scanf("%s", s);删除的地方strcpy(s, "test.txt");	if ((infile = fopen(s, "r")) == NULL)	{		printf("File %s can't be opened.\n", s);		exit(1);	}#if 1		// 增加的地方	// open the output file	finddot = strchr(s,'.');	if (finddot!=NULL){		strcpy(finddot, ".out");	}else{		strcat(s, ".out");		printf("%s\n", s);	}	printf("Output File is %s\n", s);	if ((outfile = fopen(s, "w")) == NULL)	{		printf("File %s can't be opened.\n", s);		exit(1);	}#endif		phi = createset(SYM_NULL);	relset = createset(SYM_EQU, SYM_NEQ, SYM_LES, SYM_LEQ, SYM_GTR, SYM_GEQ, SYM_NULL);		// create begin symbol sets	declbegsys = createset(SYM_CONST, SYM_VAR, SYM_PROCEDURE, SYM_NULL);	statbegsys = createset(SYM_BEGIN, SYM_CALL, SYM_IF, SYM_WHILE, SYM_NULL);	facbegsys = createset(SYM_IDENTIFIER, SYM_NUMBER, SYM_LPAREN, SYM_NULL);	err = cc = cx = ll = 0; // initialize global variables	ch = ' ';	kk = MAXIDLEN;	getsym();	set1 = createset(SYM_PERIOD, SYM_NULL);	set2 = uniteset(declbegsys, statbegsys);	set = uniteset(set1, set2);	block(set);	destroyset(set1);	destroyset(set2);	destroyset(set);	destroyset(phi);	destroyset(relset);	destroyset(declbegsys);	destroyset(statbegsys);	destroyset(facbegsys);	if (sym != SYM_PERIOD)		error(9); // '.' expected.
//**************************修改的地方
	else 
	{
		while(1) {
			while(cc<ll&&line[cc]!=-1)
			{	 
				if(line[cc]!=' '&& line[cc]!='\t') 
				{	 
					error (28);//"Follow the period is an incorrect symbol."
				    break;
				} 
			    cc++;
			}
			if (feof(infile)) break;
			else getch();
		}
	}
//***********************************	if (err == 0)	{		hbin = fopen("hbin.txt", "w");		for (i = 0; i < cx; i++)			fwrite(&code[i], sizeof(instruction), 1, hbin);		fclose(hbin);	}	if (err == 0)		interpret();	else		printf("There are %d error(s) in PL/0 program.\n", err);	listcode(0, cx);		// 增加的地方,关闭所有文件流	fclose(infile);	fclose(outfile);} // main//////////////////////////////////////////////////////////////////////// eof pl0.c

⌨️ 快捷键说明

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