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

📄 sxb2.c

📁 c语言编的PL/0的词法分析器
💻 C
📖 第 1 页 / 共 2 页
字号:
	{ // 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		//added by yzhang 02-02-28		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;	// modified by yzhang 02-03-15		} // 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;		while (levelDiff--)		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	printf("Begin executing PL/0 program.\n");	fprintf(outfile, "Begin executing PL/0 program.\n");	pc = 0;	b = 1;	top = 3;	stack[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];			case OPR_LES:				top--;				stack[top] = stack[top] < stack[top + 1];				break;			case OPR_GEQ:				top--;				stack[top] = stack[top] >= stack[top + 1];			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


symset uniteset(symset s1, symset s2)
{
	symset s;
	snode* p;
	
	s = p = (snode*) malloc(sizeof(snode));
	
// added by yzhang 02-02-28
	s1 = s1->next; s2 = s2->next; 
// end add
	
	while (s1 && s2)
	{
		p->next = (snode*) malloc(sizeof(snode));
		p = p->next;
		if (s1->elem < s2->elem)
		{
			p->elem = s1->elem;
			s1 = s1->next;
		}
		else
		{
			p->elem = s2->elem;
			s2 = s2->next;
		}
	}
	
	if ( s2 )	s1 = s2;	//added by yzhang 02-02-28

	while (s1)
	{
		p->next = (snode*) malloc(sizeof(snode));
		p = p->next;
		p->elem = s1->elem;
		s1 = s1->next;
		
	}
/* deleted by yzhang	02-02-28
	while (s2)
	{
		p->next = (snode*) malloc(sizeof(snode));
		p = p->next;
		p->elem = s2->elem;
		s2 = s2->next;
	}
*/
	p->next = NULL;

	return s;
} // uniteset

void setinsert(symset s, int elem)
{
	snode* p = s;
	snode* q;

	while (p->next && p->next->elem < elem)
	{
		p = p->next;
	}
	
	q = (snode*) malloc(sizeof(snode));
	q->elem = elem;
	q->next = p->next;
	p->next = q;
} // setinsert

symset createset(int elem, .../* SYM_NULL */)
{
//	va_list list;
	symset s;

	s = (snode*) malloc(sizeof(snode));
	s->next = NULL;

//	va_start(list, elem);
//	while (elem)
//	{
//		setinsert(s, elem);
//		elem = va_arg(list, int);
//	}
//	va_end(list);
	return s;
} // createset

void destroyset(symset s)
{
	snode* p;

	while (s)
	{
		p = s;
		s = s->next;
		free(p);
	}
} // destroyset

int inset(int elem, symset s)
{
	s ->next;
	while (s && s->elem < elem)
		s = s->next;

	if (s && s->elem == elem)
		return 1;
	else
		return 0;
} // inset

//added by yzhang 02-02-28
void showset(symset s)
{
	s = s->next;
	while (s ){
		printf("%d,", s->elem);
		s = s->next;
	}
	printf("\n");
} // showset//////////////////////////////////////////////////////////////////////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);	if ((infile = fopen(s, "r")) == NULL)	{		printf("File %s can't be opened.\n", s);		exit(1);	}#if 1		// added by yzhang  02-02-28	// 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.	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);		// close all files, added by yzhang, 02-02-28	fclose(infile);	fclose(outfile);} // main//////////////////////////////////////////////////////////////////////// eof pl0.c

⌨️ 快捷键说明

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