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

📄 prase.cpp

📁 内含源代码和编译实验报告
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	m_Entoken=m_pScaner->getToken();
	CTreeNode *t=newStmtNode(ForK);
	CTreeNode *p=t;
	CTreeNode *p2;
	match(LLPAREN,"missing '(' after 'for'");
	p->m_pchild[0]=expression();
	if(p->m_pchild[0]) p->m_pchild[0]->m_pfather=p;
	p=p->m_pchild[0];
	p->m_pbrother=expression();
	p=p->m_pbrother;
	m_EnEndexp=ERPAREN;							//指示下一个表达式将以)结尾。
	p->m_pbrother=expression();
	match(LGPAREN,"missing '{' after 'for'");
	p2=t->m_pchild[1]=compound_stmt();
	if(p2) p2->m_pfather=t;
	while(p2 && p2->m_pbrother){
		p2=p2->m_pbrother;
		p2->m_pfather=t;
	}
	return t;
}

/***************************************************************
**文法:jump_stmt->goto ID;
****************************************************************/
CTreeNode *CPraser::jump_stmt(void){
	CTreeNode *t=newStmtNode(GotoK);
	m_Entoken=m_pScaner->getToken();
	strcpy(m_strIDname, m_pScaner->GettokenString());
	if(m_Entoken!=ID)
		throw CInvalid_type(AllGlobals.lineno,"goto an illegal destination");
	t->m_pchild[0]=newExpNode(IdK);
	if(t->m_pchild[0]) t->m_pchild[0]->m_pfather=t;
	m_Entoken=m_pScaner->getToken();
	match(SEMI,"missing ';'.");
	return t;
}
	
/*************************************************
**文法:break_stmt->break;
*************************************************/
CTreeNode *CPraser::break_stmt(void){
	CTreeNode *t=newStmtNode(BreakK);
	m_Entoken=m_pScaner->getToken();
	match(SEMI, "missing ';'");
	return t;
}
	
/*************************************************
**文法:continue_stmt->continue;
************************************************/
CTreeNode *CPraser::continue_stmt(void){
	CTreeNode *t=newStmtNode(ContinueK);
	m_Entoken=m_pScaner->getToken();
	match(SEMI,"missing ';'");
	return t;
}

/**********************************************
**文法:return_stmt->return;|return expression;
***********************************************/	
CTreeNode *CPraser::return_stmt(void){
	CTreeNode *t=newStmtNode(ReturnK);
	m_Entoken=m_pScaner->getToken();
	strcpy(m_strIDname, m_pScaner->GettokenString());
	if(m_Entoken==SEMI)	m_Entoken=m_pScaner->getToken();
	else{ 
		t->m_pchild[0]=expression(); 
		if(t->m_pchild[0]) t->m_pchild[0]->m_pfather=t;}
	return t;
}

/**************************************************
**文法:expression->var=expression|logic1_expression
***************************************************/
CTreeNode *CPraser::expression(void){
	CTreeNode *t=logic1_expression();
	CTreeNode *p=t;
	if(m_Entoken==ASSIGH){
		if(t->m_pchild[0]!=NULL || t->m_EnTypevalue!=ID)//赋值语句左边不能是个复杂表达式。
			throw CInvalid_type(AllGlobals.lineno,"expression error.");
		p=newExpNode(OpK);				//建立赋值结点。
		p->m_pchild[0]=t;
		if(p->m_pchild[0]) p->m_pchild[0]->m_pfather=p;
		READSYMBOL
		t=expression();
		p->m_pchild[1]=t;
		if(p->m_pchild[1]) p->m_pchild[1]->m_pfather=p;
	}
	else{
		if(m_EnEndexp==ERPAREN){
			m_EnEndexp=ESEMI;							//恢复表达式以分号结束的缺省状态。
			if(m_Entoken!=RLPAREN)						//表达式结束处,只能是).
				throw CInvalid_type(AllGlobals.lineno,"missing ')' after expression");}
		else if(m_EnEndexp==ECOMMA){	//对于表达式由逗号结束的情况,可能读到逗号(后没有结
			if(m_Entoken==COMMA){}		//束,继续,可能读到右括号,则通知调用函数。
			else if(m_Entoken==RLPAREN) m_EnEndexp=ERPAREN;
			else throw CInvalid_type(AllGlobals.lineno,"missing ',' after expression");
			return p;}
		else{
			if(m_Entoken!=SEMI)			//表达式结尾处不能出现三种情况以外的情况。
				throw CInvalid_type(AllGlobals.lineno,"missing ';' after expression");}
		//表达式处理完毕,则取消向前多读一个记号的状态(这由最初的设计缺陷造成)
		m_Entoken=m_Enforexp;
		strcpy(m_strIDname, m_pScaner->GettokenString());
		m_Enforexp=ERROR;
	}
	return p;
}

/***************************************************************
**文法:logic1_expression->logic1_expression || logic2_expression()|logic2_expression
****************************************************************/
CTreeNode *CPraser::logic1_expression(void){
	CTreeNode *t=logic2_expression();
	CTreeNode *p=t;
	while(m_Entoken==OR){
		CTreeNode *p=newExpNode(OpK);
		p->m_pchild[0]=t;
		if(p->m_pchild[0]) p->m_pchild[0]->m_pfather=p;
		t=p;
		READSYMBOL
		p->m_pchild[1]=logic2_expression();
		if(p->m_pchild[1]) p->m_pchild[1]->m_pfather=p;
	}
	return t;
}

/******************************************************************
**文法: logic2_expression-> logic2_expression && simple_expression | simple_expression
*********************************************************************/
CTreeNode *CPraser::logic2_expression(void){
	CTreeNode *t=simple_expression();
	while(m_Entoken==AND){
		CTreeNode *p=newExpNode(OpK);
		p->m_pchild[0]=t;
		if(p->m_pchild[0]) p->m_pchild[0]->m_pfather=p;
		t=p;
		READSYMBOL
		p->m_pchild[1]=simple_expression();
		if(p->m_pchild[1]) p->m_pchild[1]->m_pfather=p;
	}
	return t;
}

/***************************************************************
**文法:simple_expression->add_expression relop add_expression|add_expression
**      relop-> <=|>=|>|<|==;
******************************************************************/
CTreeNode *CPraser::simple_expression(void){
	CTreeNode *t=add_expression();
	CTreeNode *p=t;
	while(m_Entoken>=EQ && m_Entoken<=NGT){
		p=newExpNode(OpK);
		p->m_pchild[0]=t;
		if(p->m_pchild[0]) p->m_pchild[0]->m_pfather=p;
		t=p;
		READSYMBOL
		p->m_pchild[1]=add_expression();
		if(p->m_pchild[1]) p->m_pchild[1]->m_pfather=p;
	}
	return t;
}

/******************************************************************
** 文法:  add_expression -> add_expression addop term | term
**         addop-> +|-
*****************************************************************/
CTreeNode *CPraser::add_expression(void){
	CTreeNode *t=term();
	while(m_Entoken==PLUS || m_Entoken==MINUS){
		CTreeNode *p=newExpNode(OpK);
		p->m_pchild[0]=t;
		if(p->m_pchild[0]) p->m_pchild[0]->m_pfather=p;
		t=p;
		READSYMBOL
		p->m_pchild[1]=term();
		if(p->m_pchild[1]) p->m_pchild[1]->m_pfather=p;
	}
	return t;
}

/****************************************************************
** 文法:term->logic3_expression mulop term|logic3_expression
**             mulop-> *|/
*****************************************************************/
CTreeNode *CPraser::term(void){
	CTreeNode *t=logic3_expression();
	while(m_Entoken==TIMES || m_Entoken==OVER){
		CTreeNode *p=newExpNode(OpK);
		p->m_pchild[0]=t;
		if(p->m_pchild[0]) p->m_pchild[0]->m_pfather=p;
		t=p;
		READSYMBOL
		p->m_pchild[1]=logic3_expression();
		if(p->m_pchild[1]) p->m_pchild[1]->m_pfather=p;
	}
	return t;
}

/***************************************************************
**文法: logic3_expression->!logic3_expression|factor
***************************************************************/
CTreeNode *CPraser::logic3_expression(void){
	CTreeNode *t=NULL, *p=NULL;
	if(m_Entoken==NOT){
		p=newExpNode(OpK);
		READSYMBOL
		t=factor();
		p->m_pchild[0]=t;
		if(p->m_pchild[0]) p->m_pchild[0]->m_pfather=p;
	}
	else{
		p=factor();}
	return p;
}

/*******************************************************************
**文法: factor->(expression)|ID|NUM
*******************************************************************/
CTreeNode *CPraser::factor(void){
	CTreeNode *t=NULL;
	char *p=NULL;int i=0;
	switch(m_Entoken){
		case NUM:
			p=m_strIDname;				//对数字进行有效性检查(不可出现两个小数点)
			while(*p!='\0'){
				if(*p=='.') i++;
				p++;}
			if(i>1)	throw CInvalid_type(AllGlobals.lineno,"Invalid numeric");
			t=newExpNode(ConstK);
			break;
		case ID:
			if(m_Enforexp==LLPAREN)		t=call_func();
			else	t=newExpNode(IdK);
			break;
		case CCHAR:
			t=newExpNode(ConstK);
			break;
		case LLPAREN:
			READSYMBOL
			m_EnEndexp=ERPAREN;		//指示下一个表达式将以)结束。
			t=expression();
			m_Enforexp=m_pScaner->getToken();
			return t;
		default:
			throw CInvalid_type(AllGlobals.lineno,"expression error.");
			break;
	}
	if(m_Enforexp!=ERROR){	//m_Enforexp不为ERROR,说明它保留着下一个记号,不必从文件中读取了。
		READSYMBOL}
	else{
		m_Entoken=m_pScaner->getToken();
		strcpy(m_strIDname, m_pScaner->GettokenString());
		m_Enforexp=m_pScaner->getToken();
	}//由于设计上的缺陷,在表达式处理时,扫描器始终保持向前多读一个记号,而其他部分则不具备
	 //这个功能,所以必须在这两者之间转换。
	return t;
}

/****************************************
**建一个新的函数结点或声明结点。
*****************************************/
CTreeNode *CPraser::newNode(NodeKind pa_kind){
	CTreeNode *t=new CTreeNode;
	t->m_pchild[0]=NULL;
	t->m_pchild[1]=NULL;
	t->m_pchild[2]=NULL;
	t->m_pfather=NULL;
	t->m_pbrother=NULL;
	t->m_Ennodekind=pa_kind;
	t->m_EnTypevalue=m_Enfirst;
	strcpy(t->m_strIDname, m_strIDname);
	strcpy(t->m_strScope, m_strScope);
	t->m_ilineno=AllGlobals.lineno;
	return t;
}

/**************************************************
**建一个语句体结点。
****************************************************/
CTreeNode *CPraser::newStmtNode(StmtKind pa_subkind){
	CTreeNode *t= new CTreeNode;
	t->m_pchild[0]=NULL;
	t->m_pchild[1]=NULL;
	t->m_pchild[2]=NULL;
	t->m_pfather=NULL;
	t->m_pbrother=NULL;
	t->m_Ennodekind=StmtK;
	strcpy(t->m_strScope, m_strScope);
	t->kind.m_EnStmtKind=pa_subkind;
	t->m_ilineno=AllGlobals.lineno;
	return t;
}

/***************************************************
**建一个表达式结点。
***************************************************/
CTreeNode *CPraser::newExpNode(ExpKind pa_subkind){
	CTreeNode *t= new CTreeNode;
	t->m_pchild[0]=NULL;
	t->m_pchild[1]=NULL;
	t->m_pchild[2]=NULL;
	t->m_pfather=NULL;
	t->m_pbrother=NULL;
	t->m_Ennodekind=ExpK;
	t->kind.m_EnExpKind=pa_subkind;
	t->m_EnTypevalue=m_Entoken;
	strcpy(t->m_strIDname, m_strIDname);
	strcpy(t->m_strScope, m_strScope);
	t->m_ilineno=AllGlobals.lineno;
	return t;
}

/*************************************************
**匹配掉程序中的特殊记号,如:{ (等。
*************************************************/
void CPraser::match(TokenType pa_expcted,string pa_errorifno){
	TokenType token=m_Entoken;
	m_Entoken=m_pScaner->getToken();
	strcpy(m_strIDname, m_pScaner->GettokenString());
	if(token!=pa_expcted)
		throw CInvalid_type(AllGlobals.lineno,pa_errorifno);
	return;
}

/************************************************
**打印出语法树。
***********************************************/
void CPraser::PrintTree(CTreeNode *pa_Ctree){
	int i;
	m_indentno+=4;				//用于控制缩进格式。
	while(pa_Ctree!=NULL){
		for(i=0;i<m_indentno;i++)  cout<<" ";
		if(pa_Ctree->m_Ennodekind==StmtK){
			switch(pa_Ctree->kind.m_EnStmtKind){
				case IfK:		cout<<"if"<<endl;			break;
				case WhileK:	cout<<"while"<<endl;		break;
				case ForK:		cout<<"for"<<endl;			break;
				case GotoK:		cout<<"goto"<<endl;			break;
				case BreakK:	cout<<"break"<<endl;		break;
				case ContinueK:	cout<<"continue"<<endl;		break;
				case ReturnK:	cout<<"return"<<endl;		break;
				case AddressK:  cout<<"Address"<<endl;		break;
				case CallK:		cout<<"FuncCall"<<endl;		break;
				case WritebK:	cout<<"writechar"<<endl;	break;
				case WritedK:	cout<<"writeint"<<endl;	break;
				default:
					cout<<"Unknown ExpNode kind"<<endl;
					break;}
		}
		else if(pa_Ctree->m_Ennodekind==ExpK){
			switch(pa_Ctree->kind.m_EnExpKind){
				case OpK:
					cout<<"Op: ";
					m_pScaner->printToken(pa_Ctree->m_EnTypevalue,"\0");
					break;
				case ConstK:
					cout<<"const: "<<pa_Ctree->m_strIDname<<endl;
					break;
				case IdK:
					cout<<"ID: "<<pa_Ctree->m_strIDname<<endl;
					break;
				default:
					cout<<"Unknown ExpNode kind"<<endl;
					break;}
		}
		else if(pa_Ctree->m_Ennodekind==FuncK){
			cout<<"Function: ";
			for(i=8;i<12;i++){
				if(m_pScaner->m_ReservedWords[i].m_Enwords==pa_Ctree->m_EnTypevalue){
					cout<<m_pScaner->m_ReservedWords[i].m_chwords<<" ";
					break;}
			}
			cout<<pa_Ctree->m_strIDname<<endl;}
		else if(pa_Ctree->m_Ennodekind==ParaK){
			cout<<"parameters: ";
			for(i=8;i<12;i++){
				if(m_pScaner->m_ReservedWords[i].m_Enwords==pa_Ctree->m_EnTypevalue){
					cout<<m_pScaner->m_ReservedWords[i].m_chwords<<" ";
					break;}
			}
			cout<<pa_Ctree->m_strIDname<<endl;}
		else if(pa_Ctree->m_Ennodekind==DeclK){
			cout<<"declaration: ";
			for(i=8;i<12;i++){
				if(m_pScaner->m_ReservedWords[i].m_Enwords==pa_Ctree->m_EnTypevalue){
					cout<<m_pScaner->m_ReservedWords[i].m_chwords<<" ";
					break;}
			}
			cout<<pa_Ctree->m_strIDname<<endl;}
		else
			cout<<"Unknown ExpNode kind"<<endl;
		for(i=0;i<3;i++)
			PrintTree(pa_Ctree->m_pchild[i]);
		pa_Ctree=pa_Ctree->m_pbrother;
	}
	m_indentno-=4;
}

⌨️ 快捷键说明

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