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

📄 pl0.cpp

📁 c++语言编写的PL0语言的语法分析程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			{
				getsym();
				statement(fsys, tableIndex, lev);
			}
			else
				error(10);
			}
		}
		else error(10);
		}
		if (sym == ENDSYM)
			getsym(); 
		else		
			error(17);
	}


	else if (sym == WHILESYM) {
		codeIndex1 = codeIndex;
		getsym();

		symset tempsys;
		tempsys.insert(ODDSYM);
		tempsys.insert(PLUS);
		tempsys.insert(MINUS);
		tempsys.insert(LPAREN);
		tempsys.insert(IDENT);
		tempsys.insert(NUMBER);


		condition(tempsys, tableIndex, lev);
		codeIndex2 = codeIndex;
		gen(JPC, 0, 0);
		if (sym == DOSYM)
			getsym();
		else error(18);
		statement(fsys, tableIndex, lev);
		gen(JMP, 0, codeIndex1);
		code[codeIndex2].addr = codeIndex;
	}


	else if (sym == READSYM) {
		getsym();
		if (sym == LPAREN) {
			do {
				getsym();
				if (sym == IDENT) 
					i = position(id,tableIndex);
				else i=0;
				if (i == 0)
					error(34);
				else 
				{
					if (table[i].kind != VARIABLE) {
						error(32);
						}
					else 
						{
						gen(OPR,0,16);
						gen(STO, lev - table[i].level, table[i].addr);
						}
				}
				getsym();
			} while (sym == COMMA);
		}
		else 
		{
			error(33);
			do {
				if (sym == IDENT) 
					i = position(id,tableIndex);
				else i=0;
				if (i == 0)
					error(34);
				else 
				{
					if (table[i].kind != VARIABLE) {
						error(32);
						}
					else 
						{
						gen(OPR,0,16);
						gen(STO, lev - table[i].level, table[i].addr);
						}
				}
				getsym();
			} while (sym == COMMA);
		}
		if (sym != RPAREN)
			error(22);
		else
			getsym();
	}


	else if (sym == WRITESYM) {
		getsym();
		if (sym == LPAREN) {
			do {
				getsym();
				if (sym == IDENT) 
					i = position(id,tableIndex);
				else i=0;
				if (i == 0)
					error(35);
				else 
				{
					gen(LOD, lev - table[i].level, table[i].addr);
					gen(OPR,0,14);
					gen(OPR,0,15);
				}
				getsym();
			} while (sym == COMMA);
		}
		else 
		{
			error(36);
			do {
				if (sym == IDENT) 
					i = position(id,tableIndex);
				else i=0;
				if (i == 0)
					error(35);
				else 
				{
					gen(LOD, lev - table[i].level, table[i].addr);
					gen(OPR,0,14);
					gen(OPR,0,15);
				}
				getsym();
			} while (sym == COMMA);
		}
		if (sym != RPAREN)
			error(22);
		else
			getsym();
	}
	symset s2;
	s2.insert(PERIOD);
	s2.insert(SEMICOLON);
	s2.insert(ENDSYM);
	symset tempsys1=fsys;
	tempsys1.insert(CONSTSYM);
	tempsys1.insert(VARSYM);
	tempsys1.insert(PROCSYM);
//	tempsys.clear();			//blank

	test(s2, tempsys1, 19);
	DEBUG(-1, ">-statement()");
}

void Pl0::expression(symset fsys,int tableIndex, int lev)//表达式
{
	if (sourceEnd == true)
		return;
	DEBUG(1, "<-expression();");
	
	symset s2;
	s2.insert(PERIOD);
	s2.insert(SEMICOLON);
	s2.insert(ENDSYM);
	s2.insert(RPAREN);
	s2.insert(THENSYM);
	s2.insert(DOSYM);
	s2.insert(EQL);
	s2.insert(NEQ);
	s2.insert(LSS);
	s2.insert(GTR);
	s2.insert(LEQ);
	s2.insert(GEQ);

	test(fsys,s2,40);
	symbol addop;
	if (sym >= PLUS && sym <= MINUS) {
		addop = sym;
		getsym();
		term(facbegsys, tableIndex, lev);
		if (addop == MINUS)
			gen(OPR, 0, 1);
	}
	else term(facbegsys, tableIndex, lev);
	while(sym >= PLUS && sym <= MINUS) {
		addop = sym;
		getsym();
		term(facbegsys, tableIndex, lev);
		if (addop == PLUS)
			gen(OPR, 0, 2);
		else gen(OPR, 0, 3);
	}
	symset tempsys=fsys;
	tempsys.insert(CONSTSYM);
	tempsys.insert(VARSYM);
	tempsys.insert(PROCSYM);
	test(s2,tempsys,41);
	DEBUG(-1, ">-expression();");
}

void Pl0::term(symset fsys,int tableIndex, int lev)//项
{
	if (sourceEnd == true)
		return;
	DEBUG(1, "<-term();");
	symset s2;
	s2.insert(PERIOD);
	s2.insert(SEMICOLON);
	s2.insert(ENDSYM);
	s2.insert(RPAREN);
	s2.insert(THENSYM);
	s2.insert(DOSYM);
	s2.insert(PLUS);
	s2.insert(MINUS);
	s2.insert(EQL);
	s2.insert(NEQ);
	s2.insert(LSS);
	s2.insert(GTR);
	s2.insert(LEQ);
	s2.insert(GEQ);

	test(fsys,s2,43);
	symbol mulop;
	factor(facbegsys, tableIndex, lev);
	while(sym >= TIMES && sym <= SLASH) {
		mulop = sym;
		getsym();
		factor(facbegsys, tableIndex, lev);
		if (mulop == TIMES)
			gen(OPR, 0, 4);
		else gen(OPR, 0, 5);
	}
	symset tempsys=fsys;
	tempsys.insert(CONSTSYM);
	tempsys.insert(VARSYM);
	tempsys.insert(PROCSYM);
	test(s2,tempsys,42);
	DEBUG(-1, ">-term();");
}

void Pl0::factor(symset fsys,int tableIndex, int lev)
{
	if (sourceEnd == true)
		return;
	DEBUG(1, "<-factor();");
	
	int i;
	symset s2;
	s2.insert(PERIOD);
	s2.insert(SEMICOLON);
	s2.insert(ENDSYM);
	s2.insert(RPAREN);
	s2.insert(THENSYM);
	s2.insert(DOSYM);
	s2.insert(PLUS);
	s2.insert(MINUS);
	s2.insert(TIMES);
	s2.insert(SLASH);
	s2.insert(EQL);
	s2.insert(NEQ);
	s2.insert(LSS);
	s2.insert(GTR);
	s2.insert(LEQ);
	s2.insert(GEQ);

	test(fsys,s2,42);
	while(facbegsys.find(sym) != facbegsys.end()) {	//因子开始字符
		if (sym == IDENT) {
			i = position(id, tableIndex);
			if (i == 0)
				error(11);
			else {
				switch(table[i].kind) {
				case CONSTANT:
					gen(LIT, 0, table[i].val);
					break;
				case VARIABLE:
					gen(LOD, lev - table[i].level, table[i].addr);
					break;
				case PROCEDURE:
					error(21);
					break;
				default:
					break;
				}
			}
			getsym();
		}


		else if (sym == NUMBER) {
			if (number > numMax) {
				error(31);
				number = 0;
			}
			gen(LIT, 0, number);
			getsym();
		}


		else if (sym == LPAREN) {
			getsym();

			symset tempsys;
			tempsys.insert(PLUS);
			tempsys.insert(MINUS);
			tempsys.insert(LPAREN);
			tempsys.insert(IDENT);
			tempsys.insert(NUMBER);

			expression(tempsys, tableIndex, lev);
			if (sym == RPAREN)
				getsym();
			else error(22);
		}
//		test(fsys, tempsys, 23);			//some bugs
	symset tempsys=fsys;
	tempsys.insert(CONSTSYM);
	tempsys.insert(VARSYM);
	tempsys.insert(PROCSYM);
	test(s2,tempsys,23);
	DEBUG(-1, ">-factor();");
}
}
void Pl0::condition(symset fsys,int tableIndex, int lev)//条件语句模块
{
	DEBUG(1, "<-condition();");
	symset s2;
	s2.insert(THENSYM);
	s2.insert(DOSYM);

	test(fsys,s2,44);
	symbol relop;
	symset s;
	s.insert(PLUS);
	s.insert(MINUS);
	s.insert(LPAREN);
	s.insert(IDENT);
	s.insert(NUMBER);
	if (sym == ODDSYM) {
		getsym();
		expression(s, tableIndex, lev);
		gen(OPR, 0, 6);
	}
	else {

		expression(s, tableIndex, lev);
		if (!(sym == EQL || sym == NEQ || sym == LSS || sym == GTR || sym == LEQ || sym == GEQ))
			error(20);
		else {
			relop = sym;
			getsym();
			expression(s, tableIndex, lev);
			switch(relop) {
			case EQL:	gen(OPR, 0, 8);
						break;
			case NEQ:	gen(OPR, 0, 9);
						break;
			case LSS:	gen(OPR, 0, 10);
						break;
			case GEQ:	gen(OPR, 0, 11);
						break;
			case GTR:	gen(OPR, 0, 12);
						break;
			case LEQ:	gen(OPR, 0, 13);
						break;
			default:
				break;
			}
		}
	}
	symset tempsys=fsys;
	tempsys.insert(CONSTSYM);
	tempsys.insert(VARSYM);
	tempsys.insert(PROCSYM);
	test(s2,tempsys,45);
	DEBUG(-1, ">-condition();");
}
int Pl0::base(int bas, int *store, int l) 
{
	int bas1;
	bas1 = bas;			//查找外层基址
	for (; l > 0; l--)
		bas1 = store[bas1];
	return bas1;
}
void Pl0::interpret()//解释执行目标程序函数
{
	DEBUG(1, "<-interpret();");
	const int stackSize = 500;
	int prog, bas, topReg;
	instruction instReg;
	int store[stackSize];
	topReg = 0;
	bas = 1;
	prog = 0;
	store[1] = 0;
	store[2] = 0;
	store[3] = 0;
	
//	cout << "Start PL/0." << endl;
	OUTPUT("Start PL/0.", 888);
	DEBUG(0, "Start PL/0.");
	do {
		instReg = code[prog];
		prog++;
		switch(instReg.func) {//以目标代码函数功能划分
		case LIT:
			topReg++;
			store[topReg] = instReg.addr;
			break;
		case OPR:
			switch(instReg.addr) {
			case 0:
				topReg = bas - 1;
				prog = store[topReg + 3];
				bas = store[topReg + 2];
				break;
			case 1:
				store[topReg] = -store[topReg];
				break;
			case 2:
				topReg--;
				store[topReg] += store[topReg + 1];
				break;
			case 3:
				topReg--;
				store[topReg] -= store[topReg + 1];
				break;
			case 4:
				topReg--;
				store[topReg] *= store[topReg + 1];
				break;
			case 5:
				topReg--;
				if(store[topReg + 1]==0)//判断除数是否为零
				{
					error(47);
					return;
				}
				store[topReg] /= store[topReg + 1];
				break;
			case 6:					//odd(s[t]) 奇偶判断
				store[topReg] = ((store[topReg] % 2 == 1) ?  1 : 0);
				/*if (store[topReg] % 2 == 1)
					store[topReg] = 1;
				else store[topReg] = 0;*/
				break;
			case 8:
				topReg--;		
				store[topReg] = ((store[topReg] == store[topReg + 1]) ?  1 : 0);
				break;
			case 9:
				topReg--;
				store[topReg] = ((store[topReg] != store[topReg + 1]) ?  1 : 0);
				break;
			case 10:
				topReg--;
				store[topReg] = ((store[topReg] < store[topReg + 1]) ?  1 : 0);
				break;
			case 11:
				topReg--;
				store[topReg] = ((store[topReg] >= store[topReg + 1]) ?  1 : 0);
				break;
			case 12:
				topReg--;
				store[topReg] = ((store[topReg] > store[topReg + 1]) ?  1 : 0);
				break;
			case 13:
				topReg--;
				store[topReg] = ((store[topReg] <= store[topReg + 1]) ?  1 : 0);
				break;
			case 14:
				cout << "输出:" << store[topReg] << endl;
				OUTPUT(" :output", store[topReg]);
				DEBUG(0, "output:", store[topReg]);
				topReg--;
				break;
			case 15:
				cout << "换行:"<< endl;
				cout<<endl;
				OUTPUT(" :output", '\n');
				DEBUG(0, "output:", '\n');
				break;
			case 16:
				cout << "输入一个数:" << endl;
				topReg++;
				cin >> store[topReg];
				OUTPUT(":input.", store[topReg]);
				DEBUG(0, "input a number:", store[topReg]);
				break;
			default:
				break;
			}
			break;
		case LOD:
			topReg++;
			store[topReg] = store[base(bas, store, instReg.lev) + instReg.addr];
			break;
		case STO:
			store[base(bas, store, instReg.lev) + instReg.addr] = store[topReg];
			topReg--;
			break;
		case CAL:
			store[topReg + 1] = base(bas, store, instReg.lev);
			store[topReg + 2] = bas;
			store[topReg + 3] = prog;
			bas = topReg + 1;
			prog = instReg.addr;
			break;
		case INT:
			topReg += instReg.addr;
			break;
		case JMP:
			prog = instReg.addr;
			break;
		case JPC:
			if (store[topReg] == 0)
				prog = instReg.addr;
			topReg--;
			break;
		default:
			break;
		}
	} while(prog != 0);

//	cout << "END PL/0." << endl;
	OUTPUT("END PL/0.", 888);
	DEBUG(0, "END PL/0.");

	DEBUG(-1, ">-interpret();");
}
void Pl0::OUTPUT(char *msg1, char *msg2, int i, int j, int k)
{
#ifdef OUTPUT
	out << msg1 << i << " " << " " << msg2 << " " << j << " " << k << endl;
#endif OUTPUT
}
void Pl0::OUTPUT(char *msg, int i)
{
#ifdef OUTPUT
	out << i << " " << msg << endl;
#endif OUTPUT
}

/////////////////////////////////////////////////////////  DEBUG信息输出
void Pl0::DEBUG(int into, char *msg, char c) {
#ifdef DEBUG
//	cout << msg << " " <<endl;
	if (into == 0)
		debugOut << "|      " ;

	if (into == 1) 
		++ counter;
	for (int i = 0; i < counter; i++)
		debugOut << "|      " ;
	if (into == -1)
		-- counter;

	debugOut << msg << " " << c << endl;
#endif
}
void Pl0::DEBUG(int into, char *msg, int i, int j) {
#ifdef DEBUG
//	cout << msg << " " << i <<endl;
	if (into == 0)
		debugOut << "|      " ;

	if (into == 1) 
		++ counter;
	for (int k = 0; k < counter; k++)
		debugOut << "|      " ;
	if (into == -1)
		-- counter;

	debugOut << msg << " " << i << " ";
	if (j != 99999)
		debugOut << j;
	debugOut << endl;
#endif
}

//////////////////////////////////////////////////////////

string Pl0::errorInfo[]={" ",
	"error 0001:  常数说明中“=”写成“:=”",
	"error 0002:  常数说明中的“=”后应为数字",
	"error 0003:  常数说明中的标识符后应是“=”",
	"error 0004:  const,var,procedure后应为标识符",
	"error 0005:  漏掉了‘,’或‘;’",
	"error 0006:  过程说明后的符号不正确(应是语句开始符或过程开始符)",
	"error 0007:  应是语句开始符",
	"error 0008:  过程体内语句部分的后跟符不正确",
	"error 0009:  程序皆为丢了句号‘.’",
	"error 0010:  语句之间漏了‘;’",
	"error 0011:  标识符没说明",
	"error 0012:  赋值语句中,赋值号左部标识符属性应是变量",
	"error 0013:  赋值语句左部标识符应是赋值号:=",
	"error 0014:  call后应为标识符",
	"error 0015:  call后标识符属性应为过程",
	"error 0016:  条件语句中丢了then",
	"error 0017:  丢了end或;",
	"error 0018:  while型循环语句中丢了do",
	"error 0019:  语句后的标识符不正确",
	"error 0020:  应为关系运算符",
	"error 0021:  表达式内标识符属性不能是过程",
	"error 0022:  表达式中漏掉了右括号‘)’",
	"error 0023:  因子后的非法符号",
	"error 0024:  表达式开始符不能是此符号",
	"error 0025:  文件在不该结束的地方结束了",
	"error 0026:  结束符出现在不该结束的地方",
	"error 0027:  无法识别的字符!",
	"error 0028:  缺少'=',单独的':'不是运算符!",
	"error 0029:  数的位数超过14位!",
	"error 0030:  嵌套层数超过3层!",
	"error 0031:  数越界,超过系统所允许的最大数",
	"error 0032:  read语句括号中标识符不是变量",
	"error 0033:  read后应为左括号!",
	"error 0034:  标识符没声明或read语句括号中标识符不是变量!",
	"error 0035:  标识符没声明或write语句括号中标识符不是变量!",
	"error 0036:  write后应为左括号!",
	"error 0037:  分程序应以变量声明或语句开始!",
	"error 0038:  分程序丢失结束符';'或'.'",
	"error 0039:   分程序结束符应是';',不是'.'",
	"error 0040:   表达式开始符不正确!",
	"error 0041:   表达式后的标识符不正确",
	"error 0042:  项后的标识符不正确",
	"error 0043:   项的开始符不正确!",
	"error 0043:   因子的开始符不正确!",
	"error 0044:   条件的开始符不正确!",
	"error 0045:   条件的结束符不正确!",
	"error 0046:	分程序遗漏了结束符';'!",
	"error 0047:    除数不能为零!"
};

⌨️ 快捷键说明

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