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

📄 pl0.c

📁 pl0修改后的源程序和报告 (1) 修改后的PL/0语言文本。包含词法分析(正规式)
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "set.h"#include "pl0.h"
#include "set.c"//////////////////////////////////////////////////////////////////////// print error message.void error(n){	int i;	printf("      ");	for (i = 1; i <= cc - 1; i++)		printf(" ");		fprintf(outfile, " ");	fprintf(outfile, "^\n");	printf("^\n");	fprintf(outfile, "Error %3d: %s\n", n, err_msg[n]);	printf("Error %3d: %s\n", n, err_msg[n]);	err++;} // error//////////////////////////////////////////////////////////////////////void getch(void){	if (cc == ll)	{		if (feof(infile))		{			printf("\nPROGRAM INCOMPLETE\n");			exit(1);		}		ll = cc = 0;		fprintf(outfile, "%5d  ", cx);		printf("%5d  ", cx);		while ( (!feof(infile)) // 加的部分,为了输入输出			    && ((ch = getc(infile)) != '\n'))		{			fprintf(outfile, "%c", ch);			printf("%c", ch);			line[++ll] = ch;		} // while		fprintf(outfile, "\n");		printf("\n");		line[++ll] = ' ';	}	ch = line[++cc];} // getch//////////////////////////////////////////////////////////////////////// gets a symbol from input stream.void getsym(void){	int i, k;	char a[MAXIDLEN + 1];	while (ch == ' '|| ch == '\t')		// 修改的地方,ch == '\t'		getch();	if (isalpha(ch))	{ // symbol is a reserved word or an identifier.		k = 0;		do		{			if (k < MAXIDLEN)				a[k++] = ch;			getch();		}		while (isalpha(ch) || isdigit(ch));		a[k] = 0;		strcpy(id, a);		word[0] = id;		i = NRW;		while (strcmp(id, word[i--]));		if (++i)			sym = wsym[i]; // symbol is a reserved word		else			sym = SYM_IDENTIFIER;   // symbol is an identifier	}	else if (isdigit(ch))	{ // symbol is a number.		k = num = 0;		sym = SYM_NUMBER;		do		{			num = num * 10 + ch - '0';			k++;			getch();		}		while (isdigit(ch));		if (k > MAXNUMLEN)			error(25);     // The number is too great.	}	else if (ch == ':')	{		getch();		if (ch == '=')		{			sym = SYM_BECOMES; // :=			getch();		}		else		{			sym = SYM_NULL;       // illegal?		}	}	else if (ch == '>')	{		getch();		if (ch == '=')		{			sym = SYM_GEQ;     // >=			getch();		}		else		{			sym = SYM_GTR;     // >		}	}	else if (ch == '<')	{		getch();		if (ch == '=')		{			sym = SYM_LEQ;     // <=			getch();		}		else if (ch == '>')		{			sym = SYM_NEQ;     // <>			getch();		}		else		{			sym = SYM_LES;     // <		}	}	else	{ // other tokens		i = NSYM;		csym[0] = ch;		while (csym[i--] != ch);		if (++i)		{			sym = ssym[i];			getch();		}		else		{			printf("Fatal Error: Unknown character.\n");			fprintf(outfile, "Fatal Error: Unknown character.\n");			exit(1);		}	}} // getsym//////////////////////////////////////////////////////////////////////// generates (assembles) an instruction.void gen(int x, int y, int z){	if (cx > CXMAX)	{		fprintf(outfile, "Fatal Error: Program too long.\n");		printf("Fatal Error: Program too long.\n");		exit(1);	}	code[cx].f = x;	code[cx].l = y;	code[cx++].a = z;} // gen//////////////////////////////////////////////////////////////////////// tests if error occurs and skips all symbols that do not belongs to s1 or s2.void test(symset s1, symset s2, int n){	symset s;	if (! inset(sym, s1))	{		showset(s1);		showset(s2);		printf("sym=%d, id=%s\n", sym, id);		error(n);		s = uniteset(s1, s2);		while(! inset(sym, s))			getsym();		destroyset(s);	}} // test//////////////////////////////////////////////////////////////////////
// locates identifier in symbol table.
int position(char* id)
{
	int i;
	strcpy(table[0].name, id);
	i = tx + 1;
	while (strcmp(table[--i].name, id) != 0);
	return i;
} // position//////////////////////////////////////////////////////////////////////int dx;  // data allocation index// enter object(constant, variable or procedre) into table.void enter(int kind){	mask* mk;// 加的地方,重新声明标志位	if ( position(id)> 0 ){		error(26); //Redeclared identifier.	}// end 	tx++;	strcpy(table[tx].name, id);	table[tx].kind = kind;	switch (kind)	{	case ID_CONSTANT:		if (num > MAXADDRESS)		{			error(25); // The number is too great.			num = 0;		}		table[tx].value = num;		break;	case ID_VARIABLE:		mk = (mask*) &table[tx];		mk->level = level;		mk->address = dx++;		break;	case ID_PROCEDURE:		mk = (mask*) &table[tx];		mk->level = level;		break;	} // switch} // enter//////////////////////////////////////////////////////////////////////void constdeclaration(){	if (sym == SYM_IDENTIFIER)	{		getsym();		if (sym == SYM_EQU || sym == SYM_BECOMES)		{			if (sym == SYM_BECOMES)				error(1); // Found ':=' when expecting '='.			getsym();			if (sym == SYM_NUMBER)			{				enter(ID_CONSTANT);				getsym();			}			else			{				error(2); // There must be a number to follow '='.			}		}		else		{			error(3); // There must be an '=' to follow the identifier.		}	}	else				error(4); // There must be an identifier to follow 'const', 'var', or 'procedure'.} // constdeclaration//////////////////////////////////////////////////////////////////////void vardeclaration(void){	if (sym == SYM_IDENTIFIER)	{		enter(ID_VARIABLE);		getsym();	}	else	{		error(4); // There must be an identifier to follow 'const', 'var', or 'procedure'.	}} // vardeclaration//////////////////////////////////////////////////////////////////////void listcode(int from, int to){	int i;		printf("\n");	fprintf(outfile, "\n");	for (i = from; i < to; i++)	{		printf("%5d %s\t%d\t%d\n", i, mnemonic[code[i].f], code[i].l, code[i].a);		fprintf(outfile, "%5d %s\t%d\t%d\n", i, mnemonic[code[i].f], code[i].l, code[i].a);	}	printf("\n");	fprintf(outfile, "\n");} // listcode//////////////////////////////////////////////////////////////////////void factor(symset fsys){	void expression();	int i;	symset set;	symset set1; //加的地方 		test(facbegsys, fsys, 24); // The symbol can not be as the beginning of an expression.	if (inset(sym, facbegsys)) 	{		if (sym == SYM_IDENTIFIER)		{			if ((i = position(id)) == 0)			{				error(11); // Undeclared identifier.			}			else			{				switch (table[i].kind)				{					mask* mk;				case ID_CONSTANT:					gen(LIT, 0, table[i].value);					break;				case ID_VARIABLE:					mk = (mask*) &table[i];					gen(LOD, level - mk->level, mk->address);					break;				case ID_PROCEDURE:					error(21); // Procedure identifier can not be in an expression.					break;				} // switch			}			getsym();		}		else if (sym == SYM_NUMBER)		{			if (num > MAXADDRESS)			{				error(25); // The number is too great.				num = 0;			}			gen(LIT, 0, num);			getsym();		}		else if (sym == SYM_LPAREN)		{			getsym();#if 0			set = uniteset(createset(SYM_RPAREN, SYM_NULL), fsys);#else			set1=createset(SYM_RPAREN, SYM_NULL);			set=uniteset(set1,fsys);#endif // 修改的地方 ,uniteset			expression(set);			destroyset(set);			destroyset(set1); // 增加的地方,释放set1			if (sym == SYM_RPAREN)			{				getsym();			}			else			{				error(22); // Missing ')'.			}		}		else	// 增加和修改的地方#if 0			test(fsys, createset(SYM_LPAREN, SYM_NULL), 23);#else		{			set1=createset(SYM_LPAREN, SYM_NULL);			test(fsys,set1,23);			destroyset(set1);		}#endif 	} // while} // factor//////////////////////////////////////////////////////////////////////void term(symset fsys){	int mulop;	symset set;	symset set1; // 增加的地方	#if 0	set = uniteset(fsys, createset(SYM_TIMES, SYM_SLASH, SYM_NULL));#else	set1= createset(SYM_TIMES, SYM_SLASH, SYM_NULL);	set = uniteset(fsys,set1);	destroyset(set1);#endif //修改的地方	factor(set);	while (sym == SYM_TIMES || sym == SYM_SLASH)	{		mulop = sym;		getsym();		factor(set);		if (mulop == SYM_TIMES)		{			gen(OPR, 0, OPR_MUL);		}		else		{			gen(OPR, 0, OPR_DIV);		}	} // while	destroyset(set);} // term//////////////////////////////////////////////////////////////////////void expression(symset fsys){	int addop;	symset set;	symset set1; // 增加的地方#if 0	set = uniteset(fsys, createset(SYM_TIMES, SYM_SLASH, SYM_NULL));#else	set1=createset(SYM_TIMES, SYM_SLASH, SYM_NULL);	set = uniteset(fsys,set1);	destroyset(set1);#endif // 修改的地方	if (sym == SYM_PLUS || sym == SYM_MINUS)	{		addop = sym;		getsym();		term(set);		if (addop == SYM_MINUS)		{			gen(OPR, 0, OPR_NEG);		}	}	else	{		term(set);	}	while (sym == SYM_PLUS || sym == SYM_MINUS)	{		addop = sym;		getsym();		term(set);		if (addop == SYM_PLUS)		{			gen(OPR, 0, OPR_ADD);		}		else		{			gen(OPR, 0, OPR_MIN);		}	} // while	destroyset(set);} // expression//////////////////////////////////////////////////////////////////////void condition(symset fsys){	int relop;	symset set;	if (sym == SYM_ODD)	{		getsym();		expression(fsys);		gen(OPR, 0, 6);	}	else	{		set = uniteset(relset, fsys);		expression(set);		destroyset(set);		if (! inset(sym, relset))		{			error(20);		}		else		{			relop = sym;			getsym();			expression(fsys);			switch (relop)			{			case SYM_EQU:				gen(OPR, 0, OPR_EQU);				break;			case SYM_NEQ:				gen(OPR, 0, OPR_NEQ);				break;			case SYM_LES:				gen(OPR, 0, OPR_LES);				break;			case SYM_GEQ:				gen(OPR, 0, OPR_GEQ);				break;			case SYM_GTR:				gen(OPR, 0, OPR_GTR);				break;			case SYM_LEQ:				gen(OPR, 0, OPR_LEQ);				break;			} // switch		} // else	} // else} // condition//////////////////////////////////////////////////////////////////////void statement(symset fsys)

⌨️ 快捷键说明

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