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

📄 pl0.cpp

📁 是一个很好的编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		getsym();
		if(sym==SYM_EXPL1) explanation();//处理pl0的注释
		if(sym==SYM_BEGIN)
		{
			getsym(); 
			if(sym==SYM_EXPL1) explanation();//处理pl0的注释
		    statement(fsys);
		    while(sym==SYM_SEMICOLON||inset(sym, statbegsys))
			{
				if (sym == SYM_SEMICOLON)
				{
			    	getsym();
					if(sym==SYM_EXPL1) explanation();//处理pl0的注释
				}
			    else
				{
			    	error(10);
				}
			
		    	statement(set);
			
            mask* mk;
		    i=position(id);
		    if(i==0)
			{
		    	error(11); /* Undeclared identifier.*/
			}
	     	else if(table[i].kind != ID_VARIABLE)
			{
		    	error(12); /* Illegal assignment.*/
			     i = 0;
			}
	    	getsym(); 
			if(sym==SYM_EXPL1) explanation();//处理pl0的注释
	    	if (sym == SYM_BECOMES)
			{
		    	getsym();
				if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			}
		     else
			 {
		    	error(13); /* ':=' expected.*/
			 }
	    	expression(fsys);
	    	mk = (mask*) &table[i];
	    	if (i)
			{
		    	gen(STO, level - mk->level, mk->address);
			}
		
			gen(JMP,0,cx1);
			}
			getsym(); 
			if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			if(sym!=SYM_END) error(34);
		}
		else
		{
            mask* mk;
		    i=position(id1);
		    if(i==0)
			{
		    	error(11); /* Undeclared identifier.*/
			}
	     	else if(table[i].kind != ID_VARIABLE)
			{
		    	error(12); /* Illegal assignment.*/
			     i = 0;
			}
	    	getsym(); 
			if(sym==SYM_EXPL1) explanation();//处理pl0的注释
	    	if (sym == SYM_BECOMES)
			{
		    	getsym(); 
				if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			}
		     else
			 {
		    	error(13); /* ':=' expected.*/
			 }
	    	expression(fsys);
	    	mk = (mask*) &table[i];
	    	if (i)
			{
		    	gen(STO, level - mk->level, mk->address);
			}
			gen(JMP,0,cx1);
		}
		code[cx2].a=cx;
		jx=cx;
		
		
	} 
	//>>>>>>>>>>>>>>>>>>>>>>for语句填加结束<<<<<<<<<<<<<<<<<<<<//

	else if (sym == SYM_WHILE)     /*while 语句的处理*/
	{ /* while statement*/
		cx1 = cx;
		getsym();
		if(sym==SYM_EXPL1) explanation();//处理pl0的注释
		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();
			if(sym==SYM_EXPL1) explanation();//处理pl0的注释
		}
		else
		{
			error(18); /* 'do' expected.*/
		}
		statement(fsys);
		gen(JMP, 0, cx1);
		code[cx2].a = cx;
		jx=cx;
		
	}
//<<<<<<<<<<<<<<<<<加入的exit语句和break语句<<<<<<<<<<<<<<<<<<<<<
		if(sym==SYM_EXIT)
		{                              //exit 语句
	         gen(JMP,0,jpx);
			 getsym();
			 if(sym==SYM_EXPL1) explanation();//处理pl0的注释
		}  
		else if(sym==SYM_BREAK)
		{                                //break  语句
	    	gen(JMP,0,jx);
	    	getsym(); 
			if(sym==SYM_EXPL1) explanation();//处理pl0的注释
		}
//<<<<<<<<<<<<<<<<<<exit语句和break语句结束<<<<<<<<<<<<<<<<<<<<<<< 
	set2=uniteset(fsys,createset(SYM_BREAK,SYM_ARRAY,SYM_EXIT,SYM_ELSE,SYM_NULL));
	test(set2, 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_EXPL1) explanation();//处理pl0的注释
		if (sym == SYM_CONST)     /*定义常量的处理*/
		{ /* constant declarations
			 const 声明常量时,总有';'结束,否则报错
			 const 可以声明多个常量,用','隔开
			
		  */
			getsym(); 
			if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			do
			{
				constdeclaration();
				while (sym == SYM_COMMA)//','
				{
					getsym();
					if(sym==SYM_EXPL1) explanation();//处理pl0的注释
					constdeclaration();
				}
				if (sym == SYM_SEMICOLON)//';'
				{
					getsym(); 
					if(sym==SYM_EXPL1) explanation();//处理pl0的注释
				}
				else
				{
					error(5); /* Missing ',' or ';'.*/
				}
				if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			}
			while (sym == SYM_IDENTIFIER);
			
		} /* if*/

		if (sym == SYM_VAR)       /*定义变量的处理*/
		{ /* variable declarations*/
			getsym();
			if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			do
			{   
				if(sym==SYM_ARRAY)  arraydeclaration();
			    else vardeclaration();
				while (sym == SYM_COMMA)
				{
					getsym();
					if(sym==SYM_EXPL1) explanation();//处理pl0的注释
					if(sym==SYM_ARRAY) arraydeclaration();
					if(sym==SYM_IDENTIFIER)		vardeclaration();
				}
				if (sym == SYM_SEMICOLON)
				{
					getsym(); 
					if(sym==SYM_EXPL1) explanation();//处理pl0的注释
				}
				else
				{
					error(5); /* Missing ',' or ';'.*/
				}
				if(sym==SYM_ARRAY)  arraydeclaration();
				if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			}
			while (sym == SYM_IDENTIFIER||sym==SYM_ARRAY);
			block_dx = dx;
		
		} /* if*/
//*************************************************************************
		if(sym==SYM_BOOL)
		{
			getsym();
			if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			do
			{
				booldeclaration();
				while(sym==SYM_COMMA)
				{
					getsym();
                    if(sym==SYM_EXPL1) explanation();//处理pl0的注释
                    if(sym==SYM_IDENTIFIER) booldeclaration();
				}
				if (sym == SYM_SEMICOLON)
				{
					getsym(); 
					if(sym==SYM_EXPL1) explanation();//处理pl0的注释
				}
				else
				{
					error(5); /* Missing ',' or ';'.*/
				}
				
				if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			}
			while (sym == SYM_IDENTIFIER);
			block_dx = dx;
		
		} /* if*/

//*************************************************************************
        
		while (sym == SYM_PROCEDURE)
		{ /* procedure declarations*/
			getsym(); 
			if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			if (sym == SYM_IDENTIFIER)
			{
				enter(ID_PROCEDURE);
				getsym(); 
				if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			}
		 	else
			{
		 		error(4); /* There must be an identifier to follow 'const', 'var', or 'procedure'.*/
			}
             if(sym==SYM_LPAREN)           //函数处理procedure d(p,q)
			{
				getsym();
				if(sym==SYM_EXPL1) explanation();//处理pl0的注释
				fdeclaration();
			}                               //函数处理
			
            if (sym==SYM_SEMICOLON)//函数定义开始有';'
			{
				getsym();
				if(sym==SYM_EXPL1) explanation();//处理pl0的注释
			}
			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(); 
				if(sym==SYM_EXPL1) explanation();//处理pl0的注释
				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");

	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];
//>>>>>>>>>>>>>>>>>>>>>>加入布尔运算符<<<<<<<<<<<<<<<<<<<<<<<<<<//
			case OPR_AND:  //'$$'指令
				top--;
				stack[top]*=stack[top+1];
				break;
			case OPR_OR:   //'||'指令
				top--;
				stack[top]+=stack[top+1];
				break;
			case OPR_NOT:  //'!' 指令
				top--;
                stack[top]=!stack[top+1];
				break;
//>>>>>>>>>>>>>>>>>>>>布尔运算符结束<<<<<<<<<<<<<<<<<<<<<<<<<<<//
			} /* 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]);
			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:   //用于if, while语句的条件或无条件控制转移指令
			pc = i.a;
			break;
		case JPC:   //用于if, while语句的条件或无条件控制转移指令
			if (stack[top] == 0)
				pc = i.a;
			top--;
			break;
		} /* switch*/
	}
	while (pc);

	printf("End executing PL/0 program.\n");
} /* interpret*/

/*////////////////////////////////////////*/
  void main (void )
{
	char c;
	FILE* hbin;
	char s[80];
	int i;
	symset set, set1, set2;

	printf("THE SOURCE FILE NAME IS: "); /* get file name to be compiled*/
	scanf("%s", s);
	if ((infile = fopen(s, "r")) == NULL)
	{
		printf(" The Source File %s can't be opened.\n", s);
		exit(1);
	}

	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_BOOL, SYM_PROCEDURE, SYM_NULL);
	statbegsys = createset(SYM_IDENTIFIER, SYM_BEGIN, SYM_CALL, SYM_IF, SYM_WHILE, SYM_NULL);
	facbegsys = createset(SYM_IDENTIFIER, SYM_NUMBER,  SYM_NULL);

	err = cc = cx = ll = 0; /* initialize global variables*/
	ch = ' ';
	kk = MAXIDLEN;
//while(!feof(infile))
	getsym(); 

	if(sym==SYM_EXPL1) explanation();//处理pl0的注释
  
	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)
	{
		printf("Ready to interpret? Y/N \n");
      	getchar();
	    c=getchar();
		if(c=='y'||c=='Y')
		{
		  interpret();
		}
		else exit(1);
	}
	else
		printf("There are %d error(s) in PL/0 program.\n", err);
	listcode(0, cx);
} /* main    END OF PL0.c*/

⌨️ 快捷键说明

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