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

📄 function.h

📁 编译原理实验
💻 H
字号:
#include <iostream.h>
#include "stack.h"
//#include "head.h"
#include "queue.h"
#include <string.h>

////////////////////函数声名///////////////////////
void term();
void error();
bool Is_number(char temp);
bool Is_letter(char temp);
///////////////////////////////////////////////////

int lookup(char lexeme[])		//在标识符表里查找,找到返回其下标,找不到返回0
{
	int i;
	i=total;
	while(strcmp(lexeme,table[i].name)&&(i>0))
		i--;
	return i;
}

int insert(char lexeme[])		//将标识符插入到标识符表,并返回其插入的下标
{
	int i;
	i=lookup(lexeme);
	if(i==0)
	{
		total++;
		strcpy(table[total].name,lexeme);	//将lexeme的内容复制到table[total].name里
		return total;
	}
	else
		return i;
}

void getidentifer()		//识别标识符并将其插入到标识符表中
{
	char lexeme[17];	//标识符缓冲区
	int i;
	i=0;
	while(Is_letter(buffer[position])||Is_number(buffer[position]))
	{
		if(i<16)	//标识符长度小于16的部分保留,多余部分去掉
		{
			lexeme[i]=buffer[position];
			i++;
		}
		position++;
	}
	lexeme[i]='\0';	//结束符,要自己加上去
	position--;		//让position指回当前字符
	identry=insert(lexeme);
}

bool Is_number(char temp)	//判断是否为数字
{
	if(temp>='0'&&temp<='9')
		return true;
	return false;
}

bool Is_letter(char temp)	//判断是否为英文字母
{
	if((temp>='A'&&temp<='Z')||(temp>='a'&&temp<='z'))
		return true;
	return false;
}

bool Is_operator(char temp)
{
	for(int i=0;i<6;i++)
	{
		if(temp==operators[i])
			return true;
	}
	return false;
}

double num_analy()		//数字的识别,多位整数,小数
{
	double radix,decval;
	numval=0.0;
	do {
		decval=buffer[position]-'0';		//整数部分
		numval=numval*10+decval;
		position=position+1;
	}while(Is_number(buffer[position]));
	if (buffer[position]=='.'){				//小数部分
		position=position+1;
		radix=0.1;
		while(Is_number(buffer[position]))
		{
			decval=radix*(buffer[position]-'0');
			numval=numval+decval;
			radix=radix*0.1;
			position=position+1;
		}
	}//endif
	position=position-1;		//gettoken()首先position=position+1;
	return numval;
}

void gettoken()		//求表达式的值时用
{
    do{
		   position=position+1;
		   lookahead=buffer[position];
		}while(lookahead==' ');	//不为空格时停止,跳过遇到的空格
}

void error()
{
   cout<<buffer[position]<<" :"<<"syntax error."<<endl;
}

void expre()
{
	char addoper;		//addoper=='+'||addoper=='-'
	double operand;		//减数
	int j;
	term();
	j=identry;		//记住+=或-=符号前标识符的下标,如果first+=second便记住first在table的下标
	while(lookahead=='+'||lookahead=='-')
	{
		addoper=lookahead;
		gettoken();
		if(lookahead=='=')
		{
			gettoken();
			term();
			switch(addoper){
			case '+':
				array.Push(array.Pop()+array.Pop());	//相加的结果压栈
				table[j].value=array.GetTop();
				break;
			case '-':
				operand=array.Pop();
				array.Push(array.Pop()-operand);
				table[j].value=array.GetTop();
				break;
			}//end switch
		}//end if
		else
		{
			term();
			switch(addoper){
			case'+':
				array.Push(array.Pop()+array.Pop());	//相加的结果压栈
				break;
			case'-':
				operand=array.Pop();
				array.Push(array.Pop()-operand);		//相减的结果压栈
				break;
			}//end switch
		}//end else
	}//end while
}

void factor()
{
	double variable;
	if(lookahead=='(')
	{
		gettoken();
		expre();
		if(lookahead==')')
			gettoken();
		else 
			error();
	}
	else
		if(Is_letter(buffer[position]))		//遇到字母
		{		
			getidentifer();
			if(table[identry].evaluated==false)	//未赋值
			{
				int i=0;
				do{
					cout<<table[identry].name[i];
					i++;
				}while(table[identry].name[i]!='\0');
				cout<<":";
				cin>>variable;
				table[identry].value=variable;	//对标识符表里对于的标识符赋值
				table[identry].evaluated=true;	//并将其设为已赋值
			}
			else
				variable=table[identry].value;	//若该标识符已赋值,则将该值赋给variable
			array.Push(variable);		//将数值压栈,参加运算
			gettoken();
		}
		else
			if(Is_number(lookahead))
			{	
				variable=num_analy();		//数的识别
				array.Push(variable);		//压栈
				gettoken();
			}
			else
				error();
}

void term()
{
	char multoper;			//multoper=='*'||multoper=='/'
	double operand;			//除数
	int j;
	factor();
	j=identry;	//记住在talbe中的下标
	while(lookahead=='*'||lookahead=='/'){
		multoper=lookahead;
		gettoken();
		if(lookahead=='=')
		{
			gettoken();
			factor();
			switch(multoper){
			case '*':
				array.Push(array.Pop()*array.Pop());
				table[j].value=array.GetTop();
				break;
			case '/':
				operand=array.Pop();
				if(operand!=0.0)
				{
					array.Push(array.Pop()/operand);
					table[j].value=array.GetTop();
				}
				else
					cout<<"Zero divisor."<<endl;
				break;
			}
		}
		else
		{
		factor();
		switch(multoper){
		case'*':
			array.Push(array.Pop()*array.Pop());	//把相乘的结果压栈
			break;
		case'/':
			operand=array.Pop();
			if (operand!=0.0)
				array.Push (array.Pop()/operand);	//把相除的结果压栈
			else 
				cout<<"Zero divisor."<<endl;		//0不能作除数
			break;
		default:
			break;		//可省略
		}//swith
		}//end else
	}//while
	while(lookahead=='D'||buffer[position+1]=='I'||buffer[position+2]=='V')//整除DIV
	{
		position=position+2;
		gettoken();
		factor();
		operand=array.Pop();
		if(operand!=0.0)
			array.Push(int(array.Pop()/operand));
		else
			cout<<"Zero divisor."<<endl;
	}
	while(lookahead=='M'||buffer[position+1]=='O'||buffer[position+2]=='D')//求余MOD
	{
		position=position+2;
		gettoken();
		factor();
		operand=array.Pop();
		if(operand!=0.0)
			array.Push((int)array.Pop()%(int)operand);
		else
			cout<<"Zero divisor."<<endl;
	}
}

//////////////////////以下函数为生成语法树/////////////////////////////////////////
node* expr2();
node* term2();
node* factor2();
void printtree(node *root);
void traverse(node *ptr);

///////////////////////////lookahead有关说明//////////////////////////
//	1:+		2:-		3:*		4:/		5:(		6:)
//	7:标识符		8:数字	9:整除DIV		10:求模MOD
//	11:+=	12:-=	13:*=	14:/=
//////////////////////////////////////////////////////////////////////

void gettoken2()		//语法树生成时用
{
	while(buffer[position]==' ')
		position++;
	if(Is_operator(buffer[position]))
	{
		switch(buffer[position]){
		case '+':
			lookahead=1;
			if(buffer[position+1]=='=')
			{
				lookahead=11;
				position++;
			}
			break;
		case '-':
			lookahead=2;
			if(buffer[position+1]=='=')
			{
				lookahead=12;
				position++;
			}
			break;
		case '*':
			lookahead=3;
			if(buffer[position+1]=='=')
			{
				lookahead=13;
				position++;
			}
			break;
		case '/':
			lookahead=4;
			if(buffer[position+1]=='=')
			{
				lookahead=14;
				position++;
			}
			break;
		case '(':
			lookahead=5;
			break;
		case ')':
			lookahead=6;
			break;
		}
		position++;		//要加1,因为跟求值那里已经不同了
	}
	else
		if(buffer[position]=='D'||buffer[position+1]=='I'||buffer[position+2]=='V')//整除DIV
		{
			position=position+3;
			lookahead=9;	//整除DIV
		}
		else
			if(buffer[position]=='M'||buffer[position+1]=='O'||buffer[position+2]=='D')
			{
				position=position+3;
				lookahead=10;	//求余MOD
			}
			else
				if(Is_letter(buffer[position]))
				{
					getidentifer();
					lookahead=7;
					position++;		/////////////////////
				}
				else
					if(Is_number(buffer[position]))
					{
						num_analy();
						lookahead=8;
						position++;		/////////////////
					}
					else
						if(buffer[position]=='#')
							lookahead=0;
}

node* mknode(double tokencode)
{
	node *p;
	p=new node;
	if(tokencode==1||tokencode==2||tokencode==3||tokencode==4||tokencode==9||tokencode==10||
		tokencode==11||tokencode==12||tokencode==13||tokencode==14)
	{
		p->code=tokencode;			//+,-,*,/
		p->left=NULL;
		p->right=NULL;
	}
	else
		if(tokencode==7)
		{
			p->code=7;		//标识符
			p->entry=identry;
		}
		else
			if(tokencode==8)
			{
				p->code=8;	//数字
				p->value=numval;
			}
			else
				error();
	p->No=number;
	number++;
	return p;
}

node* factor2()
{
	node *pf;
	if(lookahead==5)
	{
		gettoken2();
		pf=expr2();
		if(lookahead==6)
			gettoken2();
		else
			error();
	}
	else
		if(lookahead==7||lookahead==8)
		{
			pf=mknode(lookahead);
			gettoken2();
		}
		else
			error();
	return pf;
}

node* term2()
{
	double multoper;
	node *pt,*ptl,*ptr;
	ptl=factor2();
	while(lookahead==3||lookahead==4||lookahead==9||lookahead==10||lookahead==13||lookahead==14)
	{
		multoper=lookahead;
		gettoken2();
		ptr=factor2();
		pt=mknode(multoper);
		pt->left=ptl;
		pt->right=ptr;
		ptl=pt;
	}
	return ptl;
}

node* expr2()
{
	double addoper;
	node *pe,*pel,*per;
	pel=term2();
	while(lookahead==1||lookahead==2||lookahead==11||lookahead==12)
	{
		addoper=lookahead;
		gettoken2();
		per=term2();
		pe=mknode(addoper);
		pe->left=pel;
		pe->right=per;
		pel=pe;
	}
	return pel;
}

void printtree(node *root)
{
	cout<<"No.  "<<"node     "<<"token     "<<"lexeme"<<endl;
	number=0;
	if(root!=NULL)
		traverse(root);
}

void traverse(node *ptr)
{
	if(ptr!=NULL)
	{
		number++;
		cout<<ptr->No<<"     "<<number<<"         "<<ptr->code<<"          ";
		switch((int)ptr->code){
		case 1:
			cout<<"+"<<endl;
			break;
		case 2:
			cout<<"-"<<endl;
			break;
		case 3:
			cout<<"*"<<endl;
			break;
		case 4:
			cout<<"/"<<endl;
			break;
		case 7:
			cout<<table[ptr->entry].name<<endl;
			break;
		case 8:
			cout<<ptr->value<<endl;
			break;
		case 9:
			cout<<"DIV"<<endl;
			break;
		case 10:
			cout<<"MOD"<<endl;
			break;
		case 11:
			cout<<"+="<<endl;
			break;
		case 12:
			cout<<"-="<<endl;
			break;
		case 13:
			cout<<"*="<<endl;
			break;
		case 14:
			cout<<"/="<<endl;
			break;
		}
		if(ptr->code<=4||ptr->code==9||ptr->code==10||ptr->code==11||ptr->code==12||
			ptr->code==13||ptr->code==14)
		{
			traverse(ptr->left);
			traverse(ptr->right);
		}
	}
}
//////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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