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

📄 pl0c_2005.cpp

📁 基于Visual studio 2005的PLO源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

/*
 * 常量声明处理
 */
int constdeclaration(int *ptx, int lev, int *pdx)
{
    if(sym==ident)
    {
		getsymdo;
		if(sym==eql||sym==becomes)
		{
			if(sym==becomes)
			{
				error(1);									/* 把一写成了:= */
		    }
			getsymdo;
			if(sym==number)
			{
				enter(constant, ptx, lev, pdx);
				getsymdo;
			}
			else
			{
				error(2);									/* 常量说明=后应是数字 */
			}
		}
		else
		{
			error(3);										/* 常量说明标识后应是= */
	    }
    }
    else
    {
		error(4);											/* const后应是标识 */
    }
    return 0;
}

/*
 * 变量声明处理
 */
int vardeclaration(int *ptx, int lev, int *pdx)
{
    if(sym==ident)
    {
		enter(variable, ptx, lev, pdx);						//填写名字表
		getsymdo;
    }
    else
    {
		error(4);											/* var后应是标识 */
    }
    return 0;
}

/*
 * 输出目标代码清单
 */
void listcode(int cx0)
{
    int i;
    if(listswitch)
    {
		for(i=cx0; i<cx; i++)
		{
			printf("%d%s%d%d\n", i, mnemonic[code[i].f], code[i].l, code[i].a);
			fprintf(fa, "%d%s%d%d\n", i, mnemonic[code[i].f], code[i].l, code[i].a);
	    }
    }
}

/*
 * 语句处理
 */
int statement(bool *fsys, int *ptx, int lev)
{
    int i, cx1, cx2;
    bool nxtlev[symnum];
    if(sym==ident)											/* 准备按照赋值语句处理 */
	{
		i=position(id, *ptx);
	    if(i==0)
		{
			error(11);										/* 变量未找到 */
	    }
		else
		{
			if(table[i].kind!=variable)
			{
				error(12);									/* 赋值语句格式错误 */
			    i=0;
			}	
			else
			{
				getsymdo;
			    if(sym==becomes)
				{
					getsymdo;
				}
				else
			    {
					error(13);								/* 没有检测到赋值符号 */
				}
				memcpy(nxtlev, fsys, sizeof(bool)*symnum);
				expressiondo(nxtlev, ptx, lev);				/* 处理赋值符号右侧表达式 */
				if(i!=0)
				{											/* expression将执行一系列指令,但最终结果
															   将会保存在栈顶,执行sto命令完成赋值 */
				    gendo(sto, lev-table[i].level, table[i].adr);
			    }
			}
		}//if(i==0)
    }
    else
    {
		if(sym==readsym)									/* 准备按照read语句处理 */
	    {
			getsymdo;
			if(sym!=lparen)
			{
				error(34);								    /* 格式错误,应是左括号 */
		    }
			else
			{
				do{
					getsymdo;
					if(sym==ident)
				    {
						i=position(id, *ptx);				/* 查找要读的变量 */
				    }
					else
					{
						i=0;
					}
					if(i==0)
				    {
						error(35);							/* read()中应是声明过的变量名 */
				    }
					else
					{
						gendo(opr, 0, 16);					/* 生成输入指令,读取值到栈顶 */
					    gendo(sto, lev-table[i].level, table[i].adr);		/* 储存到变量 */
				    }
					getsymdo;
				}while(sym==comma);							/* 一条read语句可读多个变量 */
			}
		    if(sym!=rparen)
			{
				error(33);									/* 格式错误,应是右括号 */
			    while(!inset(sym, fsys))					/* 出错补救,直到收到上层函数的后跟符号 */
				{
					getsymdo;
			    }
			}
			else
			{
				getsymdo;
			}
		}
		else
		{
			if(sym==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(33);							/* write()中应为完整表达式 */
				    }
					else
					{
						getsymdo;
					}
				}
				gendo(opr, 0, 15);							/* 输出换行 */
			}
			else
			{
				if(sym==callsym)							/* 准备按照call语句处理 */
			    {
					getsymdo;
					if(sym!=ident)
					{
						error(14);							/* call后应为标识符	*/
				    }
					else
					{
						i=position(id, *ptx);
						if(i==0)
					    {
							error(11);						/* 过程未找到 */
						}
						else
						{
							if(table[i].kind==procedur)
							{
								gendo(cal, lev-table[i].level, table[i].adr);		/* 生成call指令 */
						    }
							else
							{
								error(15);					/* call后标识符应为过程 */
						    }
					    }
						getsymdo;
					}
				}
				else
				{
					if(sym==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);						/* 缺少then */
					    }
						cx1=cx;								/* 保存当前指令地址 */
					    gendo(jpc, 0, 0);					/* 生成条件跳转指令,跳转地址暂写0 */
					    statementdo(fsys, ptx, lev);		/* 处理then后的语句 */
					    code[cx1].a=cx;						/* 经statement处理后,cx为then后语句执行
															   完的位置,它正是前面未定的跳转地址 */
					}
				    else
				    {
						if(sym==beginsym)					/* 准备按照复合语句处理 */
					    {
							getsymdo;
							memcpy(nxtlev, fsys, sizeof(bool)*symnum);
							nxtlev[semicolon]=true;
							nxtlev[endsym]=true;			/* 后跟符号为分号或end */
															/* 循环调用语句处理函数,直到下一个符号不
															   是语句开始符号或收到end */
						    statementdo(nxtlev, ptx, lev);
						    while(inset(sym, statbegsys)||sym==semicolon)
						    {
								if(sym==semicolon)
								{
									getsymdo;
								}
								else
								{
									error(10);				/* 缺少分号 */
							    }
								statementdo(nxtlev, ptx, lev);
						    }
							if(sym==endsym)
							{
								getsymdo;
							}
							else
							{
								error(17);					/* 缺少end或分号 */
							}
							
						}
						else
						{
							if(sym==whilesym)				/* 准备按照while语句处理 */
						    {
								cx1=cx;						/* 保存判断条件操作的位置 */
							    getsymdo;
								memcpy(nxtlev, fsys, sizeof(bool)*symnum);
							    nxtlev[dosym]=true;			/* 后跟符号为do */
							    conditiondo(nxtlev, ptx, lev);		/* 调用条件处理 */
							    cx2=cx;						/* 保存循环体的结束的下一个位置 */
							    gendo(jpc, 0, 0);			/* 生成条件跳转,但跳出循环的地址未知 */
							    if(sym==dosym)
								{
									getsymdo;
								}
								else
								{
									error(18);				/* 缺少 do */
							    }
								statementdo(fsys, ptx, lev);		/* 循环体 */
							    gendo(jmp, 0, cx1);			/* 回头重新判断条件 */
							    code[cx2].a=cx;				/* 反填跳出循环的地址,与if类似 */
						    }
							else
							{
								memset(nxtlev, 0, sizeof(bool)*symnum);		/* 语句结束无补救集合 */
								testdo(fsys, nxtlev, 19);	/* 检测语句结束的正确性 */
							}
						}
					}
				}
			}
		}
    }
    return 0;
}

/*
 *表达式处理
 */
int expression(bool *fsys, int *ptx, int lev)
{
    enum symbol addop;										/* 用于保存正负号 */
    bool nxtlev[symnum];
    if(sym==plus||sym==minus)								/* 开头的正负号,此时当前表达式被看作一个正的
															   或负的项 */
    {
	    addop=sym;										    /* 保存开头的正负号 */
		getsymdo;
		memcpy(nxtlev, fsys, sizeof(bool)*symnum);
	    nxtlev[plus]=true;
		nxtlev[minus]=true;
		termdo(nxtlev, ptx, lev);							/* 处理项 */
	    if(addop==minus)
		{
			gendo(opr, 0, 1);								/* 如果开头为负号生成取负指令 */
	    }
    }
    else													/* 此时表达式被看作项的加减 */
    {
	    memcpy(nxtlev, fsys, sizeof(bool)*symnum);
	    nxtlev[plus]=true;
		nxtlev[minus]=true;
	    termdo(nxtlev, ptx, lev);							/* 处理项 */
    }
    while(sym==plus||sym==minus)
    {
		addop=sym;
	    getsymdo;
		memcpy(nxtlev, fsys, sizeof(bool)*symnum);
	    nxtlev[plus]=true;
		nxtlev[minus]=true;
		termdo(nxtlev, ptx, lev);							/* 处理项 */
	    if(addop==plus)
		{
			gendo(opr, 0, 2);								/* 生成加法指令 */
	    }
		else
		{
			gendo(opr, 0, 3);								/* 生成减法指令 */
	    }
    }
    return 0;
}

 /*
  * 项处理
  */
 int term(bool *fsys, int *ptx, int lev)
 {
    enum symbol mulop;										/* 用于保存乘除法符号 */
    bool nxtlev[symnum];
    memcpy(nxtlev, fsys, sizeof(bool)*symnum);
	nxtlev[times]=true;
	nxtlev[slash]=true;
    factordo(nxtlev, ptx, lev);								/*处理因子 */
    while(sym==times||sym==slash)
	{
		mulop=sym;
		getsymdo;
		factordo(nxtlev, ptx, lev);
		if(mulop==times)
		{
			gendo(opr, 0, 4);								/* 生成乘法指令 */
	    }
		else
		{
			gendo(opr, 0, 5);								/* 生成除法指令 */
	    }
	}
    return 0;
}

 /*
  * 因子处理
  */
int factor(bool *fsys, int *ptx, int lev)
{
    int i;
    bool nxtlev[symnum];
    testdo(facbegsys, fsys, 24);							/* 检测因子的开始符号 */
    while(inset(sym, facbegsys))							/* 循环直到不是因子开始符号 */
    {
	    if(sym==ident)										/* 因子为常量或变量 */
	    {
			i=position(id, *ptx);							/* 查找名字 */
		    if(i==0)
		    {
			    error(11);									/* 标识符未声明 */
		    }
			else
			{
				switch(table[i].kind)
				{
					case constant:							/* 名字为常量 */
						gendo(lit, 0, table[i].val);		/* 直接把常量的值入栈 */
						break;
					case variable:							/* 名字为变量 */
						gendo(lod, lev-table[i].level, table[i].adr);		/* 找到变量地址并将其值入栈 */
						break;
					case procedur:							/* 名字为过程 */
						error(21);							/* 不能为过程 */
						break;
				}
				getsymdo;
			}
		}
		else
		{
			if(sym==number)									/* 因子为数 */
			{
				if(num>amax)
				{
					error(31);
					num=0;
				}
				gendo(lit, 0, num);
				getsymdo;
			}
			else
			{
				if(sym==lparen)								/* 因子为表达式 */
				{
					getsymdo;
					memcpy(nxtlev, fsys, sizeof(bool)*symnum);
					nxtlev[rparen]=true;
					expressiondo(nxtlev, ptx, lev);
					if(sym==rparen)
					{
						getsymdo;
					}
					else
					{
						error(22);							/* 缺少右括号 */
					}
				}
				testdo(fsys, facbegsys, 23);				/* 因子后有非法符号 */
			}
		}
	}
	return 0;
}

/*
 *条件处理
 */
int condition(bool *fsys, int *ptx, int lev)
{
    enum symbol relop;
    bool nxtlev[symnum];
    if(sym==oddsym)											/* 准备按照odd运算处理 */
    {
		getsymdo;
		expressiondo(fsys, ptx, lev);
		gendo(opr, 0, 6);									/* 生成odd指令 */
    }
    else
    {														/* 逻辑表达式处理 */
	    memcpy(nxtlev, fsys, sizeof(bool)*symnum);
		nxtlev[eql]=true;
	    nxtlev[neq]=true;
	    nxtlev[lss]=true;
	    nxtlev[leq]=true;
	    nxtlev[gtr]=true;
	    nxtlev[geq]=true;
	    expressiondo(nxtlev, ptx, lev);
	    if(sym!=eql&&sym!=neq&&sym!=lss&&sym!=leq&&sym!=gtr&&sym!=geq)
		{
			error(20);
		}
		else
		{
		    relop=sym;
			getsymdo;
			expressiondo(fsys, ptx, lev);
		    switch(relop)
			{
				case eql:
					gendo(opr, 0, 8);
					break;
				case neq:
					gendo(opr, 0, 9);
					break;
				case lss:
					gendo(opr, 0, 10);
					break;
				case geq:
					gendo(opr, 0, 11);
					break;
				case gtr:
					gendo(opr, 0, 12);
					break;
				case leq:
					gendo(opr, 0, 13);
					break;
			}
		}
    }
    return 0;
}

/*
 * 解释程序
 */
void interpret()
{
    int p, b, t;											/* 指令指针,指令基址,栈顶指针 */
    struct instruction i;									/* 存放当前指令 */
    int s[stacksize];										/* 栈 */
    printf("start plO\n");
    t=0;
    b=0;
    p=0;
    s[0]=s[1]=s[2]=0;
    do{
		i=code[p];											/* 读当前指令 */
		p++;
		switch(i.f)
		{
			case lit:										/* 将a的值取到栈顶 */
				s[t]=i.a;
				t++;
				break;
			case opr:										/* 数学、逻辑运算 */
				switch(i.a)
				{
					case 0:
						t=b;
						p=s[t+2];
						b=s[t+1];
						break;
					case 1:
						s[t-1]=-s[t-1];
					    break;
					case 2:
					    t--;
					    s[t-1]=s[t-1]+s[t];
					    break;
					case 3:
						t--;
					    s[t-1]=s[t-1]-s[t];
					    break;
					case 4:
						t--;
					    s[t-1]=s[t-1]*s[t];
					    break;
					case 5:
					    t--;
					    s[t-1]=s[t-1]/s[t];
					    break;
					case 6:
						s[t-1]=s[t-1]%2;
						break;
					case 8:
						t--;
						s[t-1]=(s[t-1]==s[t]);
						break;
					case 9:
						t--;
						s[t-1]=(s[t-1]!=s[t]);
						break;
					case 10:
						t--;
						s[t-1]=(s[t-1]<s[t]);
						break;
					case 11:
						t--;
						s[t-1]=(s[t-1]>=s[t]);
						break;
					case 12:
						t--;
						s[t-1]=(s[t-1]>s[t]);
						break;
					case 13:
						t--;
						s[t-1]=(s[t-1]<=s[t]);
						break;
					case 14:
						printf("%d", s[t-1]);
						fprintf(fa2, "%d", s[t-1]);
						t--;
						break;
					case 15:
						printf("\n");
						fprintf(fa2, "\n");
						break;
					case 16:
						printf("?");
						fprintf(fa2, "?");
						scanf("%d", &(s[t]));
						fprintf(fa2, "%d\n", s[t]);
						t++;
						break;
				}
				break;
			case lod:										/* 取相对当前过程的数据基地址为a的内存的值到栈顶 */
				s[t]=s[base(i.l,  s, b)+i.a];
				t++;
				break;
			case sto:										/* 栈顶的值存到相对当前过程的数据基地址为a的内存 */
			    t--;
				s[base(i.l, s, b)+i.a]=s[t];
				break;
			case cal:										/* 调用子过程 */
				s[t]=base(i.l, s, b);						/* 将父过程基地址入栈 */
			    s[t+1]=b;									/* 将本过程基地址入栈,此两项用于base函数 */
			    s[t+2]=p;									/* 将当前指令指针入栈 */
			    b=t;										/* 改变基地址指针值为新过程的基地址 */
			    p=i.a;										/* 跳转 */
			    break;
			case inte:										/* 分配内存 */
			    t+=i.a;
				break;
			case jmp:										/* 直接跳转 */
				p=i.a;
				break;
			case jpc:										/* 条件跳转 */
				t--;
				if(s[t]==0)
				{
					p=i.a;
				}
				break;
		}
    }while(p!=0);
 }

  /* 通过过程基址求上l层过程的基址 */
int base(int l, int *s, int b)
{
    int b1;
    b1=b;
    while(l>0)
    {
		b1=s[b1];
		l--;
	}
    return b1;
}

⌨️ 快捷键说明

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