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

📄 pl0parser.cpp

📁 一、 pl0文法:适用于递归下降分析算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	match(ASSIGNOP);
	expression();
	code.gen("sto",curLev-table[n].level,table[n].val);
	while(tokKind==END || tokKind==SEMICOLON || tokKind==DOT)
		return;
	//赋值语句非法结束,可能表达式出现错误
	switch(tokKind)
	{
	case RPAREN:
		error("表达式缺少“(”!");
		match(RPAREN);
		//由FT'E'开始推导,且已匹配了F
		errExp();
		break;
	case LPAREN:
	case VARIABLE:
	case NUMBER:
		error("表达式缺少运算符!");
		//添加一个运算符,由FT'E'开始推导
		expression();
		break;
	default:
		error("表达式错,原因不知道!");
		while(tokKind!=SEMICOLON && tokKind!=END && tokKind!=DOT)
			match(tokKind);
	}
}

void CPl0Parser::callWord()
{
	match(CALL);
	int n=tokVal;
	match(PROCEDURE);
	int t=code.gen("call",curLev-table[n].level,table[n].val);
	if(table[n].size==-1)
		table[n].val=t;
}

void CPl0Parser::beginWord()
{
	match(BEGIN);
	word();
	while(tokKind==SEMICOLON)
	{
		match(SEMICOLON);
		word();
	}
	match(END);
}

void CPl0Parser::ifWord()
{
	match(IF);
	condition();
	int n=code.gen("jf",0,0);
	if(tokKind!=THEN)
	{
		while(1)
		{
			switch(tokKind)
			{
			case THEN:
				error("条件表达式错!");
				match(THEN);
				break;
			case ASSIGNOP:
				back();
				tokKind=VARIABLE;
			case BEGIN:
			case IF:
			case WHILE:
			case READ:
			case WRITE:
				error("条件语句缺少then!");
				break;
			case SEMICOLON:
			case END:
			case DOT:
				error("条件语句错!");
				return;
			default:
				match(tokKind);
				continue;
			}
			break;
		}
	}
	else
		match(THEN);
	word();
	code.modify(n);
}

void CPl0Parser::whileWord()
{
	match(WHILE);
	int n=code.getCodeAddr();
	condition();
	int m=code.gen("jf",0,0);
	if(tokKind!=DO)
	{
		while(1)
		{
			switch(tokKind)
			{
			case DO:
				error("条件表达式错!");
				match(DO);
				break;
			case ASSIGNOP:
				back();
				tokKind=VARIABLE;
			case BEGIN:
			case IF:
			case WHILE:
			case READ:
			case WRITE:
				error("循环语句缺少do!");
				break;
			case SEMICOLON:
			case END:
			case DOT:
				error("循环语句错!");
				return;
			default:
				match(tokKind);
				continue;
			}
			break;
		}
	}
	else
		match(DO);
	word();
	code.gen("j",0,n);
	code.modify(m);
}

void CPl0Parser::readWord()
{
	match(READ);
	match(LPAREN);
	code.gen("opr",0,16);
	code.gen("sto",curLev-table[tokVal].level,table[tokVal].val);
	match(VARIABLE);
	while(tokKind==COMMA)
	{
		match(COMMA);
		code.gen("opr",0,16);
		code.gen("sto",curLev-table[tokVal].level,table[tokVal].val);
		match(VARIABLE);
	}
	if(tokKind!=RPAREN)
	{
		error("read语句错");
		while(tokKind!=RPAREN && tokKind!=SEMICOLON)
			match(tokKind);
	}
	if(tokKind==RPAREN)
		match(RPAREN);
}

void CPl0Parser::writeWord()
{
	match(WRITE);
	match(LPAREN);
	expression();
	code.gen("opr",0,14);
	while(tokKind==COMMA)
	{
		match(COMMA);
		expression();
		code.gen("opr",0,14);
	}
	if(tokKind!=RPAREN)
	{
		error("write语句错误!");
		while(tokKind!=RPAREN && tokKind!=SEMICOLON)
			match(tokKind);
	}
	if(tokKind==RPAREN)
		match(RPAREN);
	code.gen("opr",0,15);
	while(tokKind!=SEMICOLON && tokKind!=END && tokKind!=DOT)
		match(tokKind);
}

int CPl0Code::gen(char code[],int lev,int addr)
{
	strcpy(codes[curCodePosition].code,code);
	codes[curCodePosition].level=lev;
	codes[curCodePosition].addr=addr;
	return curCodePosition++;
}

void CPl0Code::intit(CPl0Parser *p)
{
	this->pParser=p;
	curCodePosition=0;
}

void CPl0Code::modify(int pos)
{
	codes[pos].addr=curCodePosition;
}

void CPl0Code::modify(int pos,int tg)
{
	codes[pos].addr=tg;
}

int CPl0Code::getCodeAddr()
{
	return curCodePosition;
}

void CPl0Parser::errExp()
{
	while(tokKind==MULTOP || tokKind==DIVOP)
	{
		match(tokKind);
		factor();
	}
	while(tokKind==PLUSOP || tokKind==MINUSOP)
	{
		match(tokKind);
		term();
	}
}

void CPl0Parser::expression()
{
	int mbool=0;
	switch(tokKind)
	{
	case MINUSOP:
		mbool=1;
		match(MINUSOP);break;
	case PLUSOP:
		match(PLUSOP);
		break;
	}
	term();
	while(1)
	{
		switch(tokKind)
		{
		case PLUSOP:
			match(PLUSOP);
			term();
			code.gen("opr",0,2);
			continue;
		case MINUSOP:
			match(MINUSOP);
			term();
			code.gen("opr",0,3);
			continue;
		default:
			break;
		}
		break;
	}
	if(mbool)
		code.gen("opr",0,1);
}

void CPl0Parser::term()
{
	factor();
	while(1)
	{
		switch(tokKind)
		{
		case MULTOP:
			match(MULTOP);
			factor();
			code.gen("opr",0,4);
			continue;
		case DIVOP:
			match(DIVOP);
			factor();
			code.gen("opr",0,5);
			continue;
		default:
			break;
		}
		break;
	}
}

void CPl0Parser::factor()
{
	switch(tokKind)
	{
	case VARIABLE:
		code.gen("lod",curLev-table[tokVal].level,table[tokVal].val);
		match(VARIABLE);
		break;
	case NUMBER:
		code.gen("lit",0,tokVal);
		match(NUMBER);
		break;
	case CONSTANT:
		code.gen("lit",0,table[tokVal].val);
		match(CONSTANT);
		break;
	case LPAREN:
		match(LPAREN);
		expression();
		match(RPAREN);
		break;
	case IDENT:
		error("变量未定义!");
		match(tokKind);
		break;
	default:
		error("缺少运算数!");
	}
}

void CPl0Parser::condition()
{
	if(tokKind==ODD)
	{
		match(ODD);
		expression();
		code.gen("opr",0,6);
	}
	else
	{
		expression();
		switch(tokKind)
		{
		case EQ:
			match(EQ);
			expression();
			code.gen("opr",0,8);
			break;
		case NE:
			match(NE);
			expression();
			code.gen("opr",0,9);
			break;
		case GT:
			match(GT);
			expression();
			code.gen("opr",0,12);
			break;
		case GE:
			match(GE);
			expression();
			code.gen("opr",0,11);
			break;
		case LT:
			match(LT);
			expression();
			code.gen("opr",0,10);
			break;
		case LE:
			match(LE);
			expression();
			code.gen("opr",0,13);
			break;
		default:
			error(ROP);
		}
	}
}

void CPl0Parser::getCode(CString &cds)
{
	if(errStr.GetLength())
	{
		cds="";
		return;
	}
	code.getCode(cds);
}

void CPl0Code::getCode(CString &cds)
{
	char buff[81];
	cds="";
	for(int i=0;i<this->curCodePosition;i++)
	{
		sprintf(buff,"%5d  %5s%5d%5d\n",i,codes[i].code,codes[i].level,codes[i].addr);
		cds+=buff;
	}
}

void CPl0Execute::init(CPl0Code *p)
{
	this->pCode=p;
}

void CPl0Execute::Execute()
{
	sp=-1;IP=0;BX=0;b=1;
	CodeStruc *pCD;
	OutPut="";
	InPut="";
	pInPos=InPut;
	stack[0]=0;
	stack[1]=0;
	stack[2]=0;
	while(b)
	{
		if(IP==20)
			IP=IP;
		pCD=pCode->codes+IP++;
		if(strcmp(pCD->code,"lit")==0)
			LIT(pCD->addr);
		else if(strcmp(pCD->code,"lod")==0)
			LOD(pCD->level,pCD->addr);
		else if(strcmp(pCD->code,"sto")==0)
			STO(pCD->level,pCD->addr);
		else if(strcmp(pCD->code,"call")==0)
			CALL(pCD->level,pCD->addr);
		else if(strcmp(pCD->code,"int")==0)
			INT(pCD->addr);
		else if(strcmp(pCD->code,"j")==0)
			JMP(pCD->addr);
		else if(strcmp(pCD->code,"jf")==0)
			JPC(pCD->addr);
		else if(strcmp(pCD->code,"opr")==0)
			OPR(pCD->addr);
	}
	MessageBox(0,OutPut,"运算结果",0);
}

void CPl0Execute::LIT(int a)
{
	stack[++sp]=a;
}

void CPl0Execute::LOD(int l,int a)
{
	int sl=BX;
	while(l-->0)
		sl=stack[sl];
	stack[++sp]=stack[sl+a];
}

void CPl0Execute::STO(int l,int a)
{
	int sl=BX;
	while(l-->0)
		sl=stack[sl];
	stack[sl+a]=stack[sp--];
}

void CPl0Execute::CALL(int l,int a)
{
	int sl=BX;
	while(l-->0)
		sl=stack[sl];
	stack[sp+1]=sl;
	stack[sp+2]=BX;
	stack[sp+3]=IP;
	IP=a;
	BX=sp+1;
}

void CPl0Execute::INT(int a)
{
	sp+=a;
}

void CPl0Execute::JMP(int a)
{
	IP=a;
}

void CPl0Execute::JPC(int a)
{
	if(stack[sp--]==0)
		IP=a;
}

void CPl0Execute::OPR(int a)
{
	char buf[80];
	const char *p;
	switch(a)
	{
	case 0:
		if(stack[BX+2]==0)
		{
			b=0;
			break;
		}
		IP=stack[BX+2];
		sp=BX-1;
		BX=stack[sp+2];
		break;
	case 1:
		stack[sp]=-stack[sp];
		break;
	case 2:
		stack[sp-1]+=stack[sp];
		sp--;
		break;
	case 3:
		stack[sp-1]-=stack[sp];
		sp--;
		break;
	case 4:
		stack[sp-1]*=stack[sp];
		sp--;
		break;
	case 5:
		stack[sp-1]/=stack[sp];
		sp--;
		break;
	case 6:
		stack[sp]=stack[sp]%2;
		break;
	case 8:
		stack[sp-1]=stack[sp-1]==stack[sp];
		sp--;
		break;
	case 9:
		stack[sp-1]=stack[sp-1]!=stack[sp];
		sp--;
		break;
	case 10:
		stack[sp-1]=stack[sp-1]<stack[sp];
		sp--;
		break;
	case 11:
		stack[sp-1]=stack[sp-1]>=stack[sp];
		sp--;
		break;
	case 12:
		stack[sp-1]=stack[sp-1]>stack[sp];
		sp--;
		break;
	case 13:
		stack[sp-1]=stack[sp-1]<=stack[sp];
		sp--;
		break;
	case 14:
		sprintf(buf,"%d  ",stack[sp--]);
		OutPut+=buf;
		break;
	case 15:
		sprintf(buf,"\n");
		OutPut+=buf;
		break;
	case 16:
		while(*(p=pInPos) && *p==' ') pInPos++;
		while(*pInPos && isdigit(*pInPos))
			pInPos++;
		if(p==pInPos)
		{
			CInputData inDlg;
			if(inDlg.DoModal()==IDOK)
			{
				InPut=inDlg.m_data;
				pInPos=InPut;
			}
			while(*(p=pInPos) && *p==' ') pInPos++;
			while(*pInPos && isdigit(*pInPos))
				pInPos++;
		}
		stack[++sp]=atoi(p);
		break;
	}
}

void CPl0Parser::Execute(const char *p)
{
	pl0(p);
	CPl0Execute exe;
	exe.init(&code);
	exe.Execute();
}

⌨️ 快捷键说明

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