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

📄 pl0dlg.cpp

📁 编译原理的课程设计,对PL0进行扩充完成内容如下:1. 基本内容: (1)增加单词:保留字;运算符 (2)修改单词:不等号# 改为 <> (3)增加条件语句的ELSE子句 (4)扩
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			}
			getsymdo;
		}
		else
		{
			error(48,line);
		}
		break;

	case decsym:        /*处理形如--b的语句*/
		getsymdo;
		if(sym==ident)
		{
			i=position(id,*ptx);
			if(i==0)
			{
				error(11,line);
			}
			else
			{
				if(table[i].kind==variable)
				{
					gendo(lod,lev-table[i].level,table[i].adr);
					gendo(lit,0,1);
					gendo(opr,0,3);
					gendo(sto,lev-table[i].level,table[i].adr);
				}
				else
				{
					error(48,line);
				}
			}
			getsymdo;
		}
		else
		{
			error(48,line);
		}
		break;

	case ident:   /*准备按照表达式语句处理*/
		i=position(id,*ptx);
		if(i==0)
   	 	{
   	 		error(11,line);
   	 	}
   	 	else
   	 	{
			if(table[i].kind==variable || table[i].kind==array)
   	 		{
				if(table[i].kind==array)   /*标识符是数组*/
				{
					getsymdo;
					if(sym==lepa)          /*数组的[*/
					{
						getsymdo;
						memcpy(nxtlev,fsys,sizeof(bool)* symnum);
						nxtlev[ripa]=true;
						expressiondo(nxtlev,ptx,lev);						
						if(sym!=ripa)        /*缺少]*/
						{
							error(38,line-1);
						}
					}
				}
				getsymdo;
				switch(sym)
				{ 
				case eql:              /*如果是=则说明赋值语句有错*/
					error(42,line);
					getsymdo;
					memcpy(nxtlev,fsys,sizeof(bool)* symnum);
					expressiondo(nxtlev,ptx,lev);
					break;
				case becomes:         /* 解释:=语句 */
					getsymdo;
					memcpy(nxtlev,fsys,sizeof(bool)* symnum);
					expressiondo(nxtlev,ptx,lev);
					break;

				case incsym:           /* 解释形如a++语句 */
					gendo(lod,lev-table[i].level,table[i].adr);
					gendo(lit,0,1);
					gendo(opr,0,2);  /*执行加法运算*/
					getsymdo;
					break;
					
				case decsym:           /* 解释形如a--语句 */
					gendo(lod,lev-table[i].level,table[i].adr);
					gendo(lit,0,1);  
					gendo(opr,0,3);   /*执行减法运算*/
					getsymdo;
					break;

				case plueql:           /* 解释+=语句 */
					gendo(lod,lev-table[i].level,table[i].adr);
					getsymdo;
					memcpy(nxtlev,fsys,sizeof(bool)* symnum);
					expressiondo(nxtlev,ptx,lev);
					gendo(opr,0,2);  /*执行加法运算*/
					break;

				case mineql:          /* 解释-=语句 */
					gendo(lod,lev-table[i].level,table[i].adr);
					getsymdo;
					memcpy(nxtlev,fsys,sizeof(bool)* symnum);
					expressiondo(nxtlev,ptx,lev);
					gendo(opr,0,3);  /*执行减法运算*/
					break;

				case muleql:        /* 解释*=语句 */
					gendo(lod,lev-table[i].level,table[i].adr);
					getsymdo;
					memcpy(nxtlev,fsys,sizeof(bool)* symnum);
					expressiondo(nxtlev,ptx,lev);
					gendo(opr,0,4);  /*执行乘法运算*/
					break;

				case diveql:        /* 解释/=语句 */
					gendo(lod,lev-table[i].level,table[i].adr);
					getsymdo;
					memcpy(nxtlev,fsys,sizeof(bool)* symnum);
					expressiondo(nxtlev,ptx,lev);
					gendo(opr,0,5);   /*执行除法运算*/
					break;
						
				default:
					error(8,line);
					break;
				}
			}
			else
			{
				error(12,line);
				i=0;
			}
			if(i!=0)
			{
				if(table[i].kind==array)
				{
					gendo(kep,lev-table[i].level,table[i].adr);  /*如果是数组,则用取数组值的指令*/
				}
				else
					gendo(sto,lev-table[i].level,table[i].adr);  /*如果是变量*/
			}
		}
		break;

	case readsym:      /*准备按照read语句处理*/ 
		getsymdo;
		if(sym!=lparen)
		{
			error(34,line);
		}
    	else
		{
    	   	do{
				getsymdo;
    	   	   	if(sym==ident)
    	   	   	{
    	   	   	  	i=position(id, *ptx);
					if(table[i].kind==array)    /*如果输入的是数组*/
					{
						getsymdo;
						if(sym==lepa)
						{
							getsymdo;
							memcpy(nxtlev,fsys,sizeof(bool)* symnum);
							nxtlev[ripa]=true;
							expressiondo(nxtlev,ptx,lev);
							if(sym!=ripa)
							{
								error(38,line-1);   /*缺少]*/
							}								
						}
					}
				}
    	   	   	else
    	   	   	{
    	   	   	  	i=0;
    	   	   	}
    	   	   	if(i==0)
    	   	   	{
    	   	   	 	error(11,line);
    	   	   	}
    	   	   	else
    	   	   	{
    	   	   		gendo(opr,0,16);
					if(table[i].kind==array)
					{
						gendo(kep,lev-table[i].level,table[i].adr);
					}
					else
						gendo(sto,lev-table[i].level,table[i].adr);	/* 储存到变量*/
				}
				getsymdo;
			}while (sym==comma);	/*一条read语句可读多个变量 */
		}
		if(sym!=rparen)
		{
			error(35,line-1);			/* 格式错误,应是右括号*/
			while(!inset(sym,fsys))   /* 出错补救,直到收到上层函数的后跟符号*/
			{
				getsymdo;
			}
		}
		else
		{
			getsymdo;
		}
		break;

	case writesym:     /* 准备按照write语句处理,与read类似*/
		getsymdo;
		if(sym==lparen)
		{
			do{
				getsymdo;
				memcpy(nxtlev,fsys,sizeof(bool)*symnum);
				nxtlev[rparen]=true;
				nxtlev[comma]=true;		/* write的后跟符号为)or,*/
				expressiondo(nxtlev,ptx,lev);/* 调用表达式处理,此处与read不同,read为给变量赋值*/
				gendo(opr,0,14);/* 生成输出指令,输出栈顶的值*/
			}while(sym==comma);
			if(sym!=rparen)
			{
				error(44,line-1);/* write()应为完整表达式*/
			}
			else
			{
				getsymdo;
			}
		}
		else
		{
			error(43,line);
		}
		gendo(opr,0,15);		/* 输出换行*/
		break;

	case callsym:      /* 准备按照call语句处理*/
		getsymdo;
		if(sym!=ident)
		{
			if(sym==semicolon)
			{
				error(45,line-1);           /*call后漏掉了标识符*/
			}
			else
			{
				error(14,line);           /*call后应为标识符*/
				getsymdo;
			}
		}
		else
		{
			i=position(id,*ptx);
			if(i==0)
			{
				error(11,line);          /*过程名未找到*/
			}
			else
			{
				if(table[i].kind==procedur)
				{
					gendo(cal,lev-table[i].level,table[i].adr);  /*生成call指令*/
				}
				else
				{
					error(15,line);      /*call后标识符应为过程*/
				}
			}
			getsymdo;
		}
		break;

	case ifsym:    /*准备按照if语句处理*/
		getsymdo;
		memcpy(nxtlev,fsys,sizeof(bool)*symnum);
		nxtlev[thensym]=true;
		nxtlev[dosym]=true;    /*后跟符号为then或do*/
		conditiondo(nxtlev,ptx,lev);   /*调用条件处理(逻辑运算)函数*/
		if(sym==thensym)
		{
			getsymdo;
		}
		else
		{
			error(16,line-1);          /*缺少then*/
		}
		cx3[ifi++]=cx;                /*保存当前指令地址,cx3为一个全局变量的数组*/
		gendo(jpc,0,0);              /*生成条件跳转指令,跳转地址暂写0*/
		statementdo(fsys,ptx,lev);   /*处理then后的语句*/
		code[cx3[--ifi]].a=cx;      /*经statement处理后,cx为then后语句执行
                                                    完的位置,它正是前面未定的跳转地址*/
		if(sym==elsesym)        /*准备按照else语句处理*/
		{
			getsymdo;
			code[cx3[ifi]].a=code[cx3[ifi]].a+1;  /*如果有else语句,当if条件为假,则跳转执行else后的语句*/
			cx4[elsei++]=cx;       /*保存当前指令地址,cx4为一个全局变量的数组*/
			gendo(jmp,0,0);        /*生成无条件跳转指令,跳转地址暂写0*/
			statementdo(fsys,ptx,lev);   /*处理else后的语句*/
			for(k=0;k<elsei;k++)
			{
				code[cx4[k]].a=cx;    /*经statement处理后,cx为整个if语句执行完的位置的下一个位置*/
			}
		}
		break;

	case forsym:   /*准备按照for语句处理*/
		getsymdo;
		if(sym==ident)
		{
			i=position(id,*ptx);
			if(i==0)
			{
				error(11,line);    /*变量未找到*/
			}
			else
			{
				if(table[i].kind!=variable) 
				{
					error(12,line);   /*赋值语句格式错误*/
					i=0;
				}
				else
				{
					getsymdo;
					if(sym==becomes)
					{
						getsymdo;
					}
					else
					{
						if(sym==eql)
						{
							error(42,line);
							getsymdo;
						}
						else
							error(13,line);   /*没有检测到赋值符号*/
					}
					memcpy(nxtlev,fsys,sizeof(bool)*symnum);
					nxtlev[tosym]=true;
					nxtlev[downtosym]=true; /*后跟符号为to或downto*/
					expressiondo(nxtlev,ptx,lev); /*处理赋值符号右侧表达式*/
					if(i!=0)
					{
						gendo(sto,lev-table[i].level,table[i].adr); /*保存初值*/
					}
					switch(sym)
					{
					case tosym:  /*循环变量逐渐增大*/
						getsymdo;
						cx1=cx;   /*保存循环变值跟终值进行比较操作的有关位置*/
						gendo(lod,lev-table[i].level,table[i].adr); /*将循环变值入栈*/
						memcpy(nxtlev,fsys,sizeof(bool)*symnum);
						nxtlev[dosym]=true;  /*后跟符号为do*/
						expressiondo(nxtlev,ptx,lev); /*调用终值的表达式处理*/
						gendo(opr,0,13);   /*判断循环变量是否小于等于终值*/
						cx2=cx;   /*保存循环体结束的下一个位置*/
						gendo(jpc,0,0); /*生成条件跳转,但跳出循环的地址未知*/
						if(sym==dosym)  /*步长为1*/
						{
							getsymdo;
							statementdo(fsys,ptx,lev);   /*循环体*/
							gendo(lod,lev-table[i].level,table[i].adr);
							gendo(lit,0,1);
							gendo(opr,0,2);
							gendo(sto,lev-table[i].level,table[i].adr); /*循环变量加1*/
							gendo(jmp,0,cx1);  /*回头重新判断条件*/
							code[cx2].a=cx;    /*回填跳出循环的地址*/
						}
						else
						{
							if(sym==stepsym)  /*步长不为1*/
							{
								getsymdo;
								gendo(inte,0,1);  /*开辟一个新的空间存放步长的值*/
								expressiondo(nxtlev,ptx,lev);
								ptx2=*ptx;
								while(table[ptx2].kind !=variable)  /*寻找最后一个在声明语句中定义的变量*/
								{
									ptx2--;
								}
								gendo(sto,0,table[ptx2].adr+1);  /*把"表达式"结果保存在新开辟的空间,即之前最后一个变量的下一个地址*/
								if(sym==dosym)
								{
									getsymdo;
									statementdo(fsys,ptx,lev);
									gendo(lod,lev-table[i].level,table[i].adr);
									gendo(lod,0,table[ptx2].adr+1);  /*取出步长的值*/
									gendo(opr,0,2);
									gendo(sto,lev-table[i].level,table[i].adr); /*循环变量加上步长的值*/
									gendo(jmp,0,cx1);  /*回头重新判断条件*/
									code[cx2].a=cx;    /*回填跳出循环的地址*/
								}
								else
								{
									error(46,line-1);  /*语句中丢了"do"*/
								}								
							}
							else
							{
								error(29,line-1);  /* 语句中丢了"step" */
							}
						}
						break;

					case downtosym:     /*循环变量逐渐减少*/
						getsymdo;
						cx1=cx;   /*保存循环变值跟终值进行比较操作的有关位置*/
						gendo(lod,lev-table[i].level,table[i].adr); /*将循环变值入栈*/
						memcpy(nxtlev,fsys,sizeof(bool)*symnum);
						nxtlev[stepsym]=true;
						nxtlev[dosym]=true;  /*后跟符号为do*/
						expressiondo(nxtlev,ptx,lev); /*调用终值的表达式处理*/
						gendo(opr,0,11);   /*判断循环变量是否小于等于终值*/
						cx2=cx;   /*保存循环体结束的下一个位置*/
						gendo(jpc,0,0); /*生成条件跳转,但跳出循环的地址未知*/
						if(sym==dosym)  /*步长为-1*/
						{
							getsymdo;
							statementdo(fsys,ptx,lev);   /*循环体*/
							gendo(lod,lev-table[i].level,table[i].adr);
							gendo(lit,0,1);
							gendo(opr,0,3);
							gendo(sto,lev-table[i].level,table[i].adr); /*循环变量加1*/
							gendo(jmp,0,cx1);  /*回头重新判断条件*/
							code[cx2].a=cx;    /*回填跳出循环的地址*/
						}
						else
						{
							if(sym==stepsym)  /*步长不为-1*/
							{
								getsymdo;
								gendo(inte,0,1);  /*开辟一个新的空间存放步长的值*/
								expressiondo(nxtlev,ptx,lev);
								ptx2=*ptx;
								while(table[ptx2].kind !=variable)  /*寻找最后一个在声明语句中定义的变量*/
								{
									ptx2--;
								}
								gendo(sto,0,table[ptx2].adr+1);  /*把"表达式"结果保存在新开辟的空间,即之前最后一个变量的下一个地址*/
								if(sym==dosym)
								{
									getsymdo;
									statementdo(fsys,ptx,lev);   /*循环体*/
									gendo(lod,lev-table[i].level,table[i].adr);
									gendo(lod,0,table[ptx2].adr+1);   /*取出步长的值*/
									gendo(opr,0,3);
									gendo(sto,lev-table[i].level,table[i].adr); /*循环变量减掉步长的值*/
									gendo(jmp,0,cx1);  /*回头重新判断条件*/
									code[cx2].a=cx;    /*回填跳出循环的地址*/
								}
								else
								{
									error(46,line-1);  /* 语句中丢了"do" */
								}								
							}
							else
							{
								error(29,line);  /* 语句中丢了"step" */
							}
						}
						break;
					default:
						error(22,line-1);   /* 语句中缺少了"to"或"downto" */
						break;											
					}

				}
			}
		}
		else
		{
			error(12,line);    /* 赋值语句左部标识符应是变量 */
		}
		break;

    case casesym:
		casej=0;
		getsymdo;
		gendo(inte,0,1);  /*开辟一个地址空间保存"表达式"计算的结果*/
		memcpy(nxtlev,fsys,sizeof(bool)*symnum);
		nxtlev[ofsym]=true;    /*case语句后的表达式后跟符号为of*/
		expressiondo(nxtlev,ptx,lev);
		ptx2=*ptx;
		while(table[ptx2].kind !=variable)  /*寻找最后一个在声明语句中定义的变量*/
		{
			ptx2--;
		}
        gendo(sto,0,table[ptx2].adr+1);  /*把"表达式"结果保存在新开辟的空间,即之前最后一个变量的下一个地址*/
		if(sym==ofsym)
		{
			getsymdo;
		}
		else
		{
			error(37,line-1);  /*缺少了of*/
		}
		while(sym!=endsym) /*case以end作为结束符*/
		{
			casei=0;
			while(sym==number)  /*case值表是一些用逗号分开的常数*/
			{
				gendo(lod,0,table[ptx2].adr+1);
				gendo(lit,0,num);
				gendo(opr,0,9);   /*判断值表中的常数是否与之前"表达式"计算的结果相等*/
				cx5[casei++]=cx;  /* 记录需要回填的地址的序号*/
				gendo(jpc,0,0);  /*如果相等,则跳转到此值表后面的语句继续执行,如果不等则继续比较些值表后面的常数*/
				getsymdo;
				if(sym==comma)
					getsymdo;
			}
			if(sym==colon)
			{
				cx1=cx;
				gendo(jmp,0,0);  /*如果此值表的值都不等于"表达式"的结果,则跳转到下一个case语句*/
				for(k=0;k<casei;k++)  
					code[cx5[k]].a=cx;  /*把开始执行值表后面语句的第一个位置回填*/
				getsymdo;
			}
			statementdo(nxtlev,ptx,lev);  /*每条case语句后面的循环体*/
			cx6[casej++]=cx;   /*记录需要回填的地址序号*/
			gendo(jmp,0,0);  /*执行此case语句后,需要跳转出case循环*/
			code[cx1].a=cx; /*回填相对于上面case语句的下一条case语句的位置*/
			if(sym==semicolon)
			{
				getsymdo;
			}
		}
		if(sym==endsym)
		{
			getsymdo;
			for(k=0;k<casej;k++)
				code[cx6[k]].a=cx;  /* 把case循环体结束的下一个位置回填*/
		}
		break;

	case repeatsym:
		cx1=cx;          /*记录循环体开始的位置*/
		getsymdo;
		while(sym!=untilsym && !inset(sym,statbegsys) && sym!=endsym)
		{
			memcpy(nxtlev,fsys,sizeof(bool)*symnum);
			nxtlev[semicolon]=true;
			nxtlev[untilsym]=true;
			statementdo(nxtlev,ptx,lev);  /*循环体*/
			if(sym==semicolon)
			{
				getsymdo;
			}
		}
		if(sym==untilsym)
		{
			getsymdo;
			memcpy(nxtlev,fsys,sizeof(bool)*symnum);  /*表达式处理*/
			nxtlev[semicolon]=true;
			conditiondo(nxtlev,ptx,lev);
			gendo(jpc,0,cx1);  /*如果条件为假,则跳转到上面的循环体继续执行,直到条件为真*/
		}
		else
		{
			error(17,line);
		}

⌨️ 快捷键说明

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