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

📄 function.h

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

int lookup(char lexeme[])
{
	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(isalpha(buffer[position])||isdigit(buffer[position]))//(Is_letter(buffer[position])||Is_number(buffer[position]))
	{
		if(i<16)
		{
			lexeme[i]=buffer[position];
			i++;
		}
		position++;
	}
	lexeme[i]='\0';
	position--;		//让position指回当前字符
	identry=insert(lexeme);
}

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(isdigit(buffer[position]));
	if (buffer[position]=='.'){				//小数部分
		position=position+1;
		radix=0.1;
		while(isdigit(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 error()
{
	isok=false;
	if(f_error==true)
	{
		CString str;
		str.Format("位置%d输入错误!",position-1);
		AfxMessageBox(str);
		buffer[position]='#';
		f_error=false;
	}
	
}

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

void gettoken()		//语法树生成时用
{
	while(buffer[position]==' ')
		position++;
	if(Is_operator(buffer[position]))
	{
		switch(buffer[position]){
		case '+':
			lookahead=1;
			position++;
			while(buffer[position]==' ')
				position++;
			if(buffer[position]=='=')
			{
				lookahead=11;
				position++;
			}
			break;
		case '-':
			lookahead=2;
			position++;
			while(buffer[position]==' ')
				position++;
			if(buffer[position]=='=')
			{
				lookahead=12;
				position++;
			}
			break;
		case '*':
			lookahead=3;
			position++;
			while(buffer[position]==' ')
				position++;
			if(buffer[position]=='=')
			{
				lookahead=13;
				position++;
			}
			break;
		case '/':
			lookahead=4;
			position++;
			while(buffer[position]==' ')
				position++;
			if(buffer[position]=='=')
			{
				lookahead=14;
				position++;
			}
			break;
/*		case '\\':
			lookahead=9;
			position++;
			break;
		case '%':
			lookahead=10;
			position++;
			break;
*/
		case '(':
			lookahead=5;
			position++;
			break;
		case ')':
			lookahead=6;
			position++;
			break;
		}
	}
	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(isalpha(buffer[position]))//(Is_letter(buffer[position]))
				{
					getidentifer();
					lookahead=7;
					position++;		/////////////////////
				}
				else
					if(isdigit(buffer[position]))//(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;
			p->left=NULL;		//////////////
			p->right=NULL;		/////////////
		}
		else
			if(tokencode==8)
			{
				p->code=8;	//数字
				p->value=numval;
				p->left=NULL;		//////////////
				p->right=NULL;		/////////////
			}
			else
				error();
	p->No=number;
	number++;
	q.EnQueue(p);
	return p;
}

node* factor()
{
	node *pf;
	if(lookahead==5)
	{
		gettoken();
		pf=extr();
		if(lookahead==6)
			gettoken();
		else
			error();
	}
	else
		if(lookahead==7||lookahead==8)
		{
			pf=mknode(lookahead);
			gettoken();
		}
		else
			error();
	return pf;
}

node* term()
{
	double multoper;
	node *pt,*ptl,*ptr;
	ptl=factor();
	while(lookahead==3||lookahead==4||lookahead==9||lookahead==10)
	{
		multoper=lookahead;
		gettoken();
		ptr=factor();
		pt=mknode(multoper);
		pt->left=ptl;
		pt->right=ptr;
		ptl=pt;
	}
	return ptl;
}

node* expr()
{
	double addoper;
	node *pe,*pel,*per;
	pel=term();
	while(lookahead==1||lookahead==2)
	{
		addoper=lookahead;
		gettoken();
		per=term();
		pe=mknode(addoper);
		pe->left=pel;
		pe->right=per;
		pel=pe;
	}
	return pel;
}

node *extr()
{
	double addoper;
	node *pe,*pel,*per;
	pel=expr();
	while(lookahead==11||lookahead==12||lookahead==13||lookahead==14)
	{
		addoper=lookahead;
		gettoken();
		per=expr();
		pe=mknode(addoper);
		pe->left=pel;
		pe->right=per;
		pel=pe;
	}
	return pel;
}

void ZuoBiao(node *ptr,node *parent,int row)	//计算各个结点的坐标
{
	if(ptr!=NULL)
	{
		xy *p=new xy;
		if(parent->left==ptr)	//左孩子
		{
			p->x=Pos[parent->No]->x-200+row*40;
			p->y=Pos[parent->No]->y+100;
			Pos[ptr->No]=p;
		}
		else
		{
			p->x=Pos[parent->No]->x+200-row*40;
			p->y=Pos[parent->No]->y+100;
			Pos[ptr->No]=p;
		}
		row++;
		if(ptr->code<=4||ptr->code>=9)
		{
			ZuoBiao(ptr->left,ptr,row);
			ZuoBiao(ptr->right,ptr,row);
		}
	}
	listnode *p;
	p=q.front->next;
	///////若最左的结点超出屏幕范围,则将它移到屏幕内/////////
	int delta=0-Pos[p->data->No]->x;
	if(delta>0)
	{
		for(int i=1;i<100;i++)
		{
			if(Pos[i]!=NULL)
				Pos[i]->x+=delta+5;
		}
		m_x+=delta+5;
	}
	///////////////////////////////////////////////////////////
}

int ErrorTest(node* ptr)
{
	if(ptr!=NULL)
	{
		listnode *p;
		p=q.front->next;
		while(p!=NULL)
		{
			if(p->data->code!=7&&p->data->code!=8&&(p->data->left==NULL||p->data->right==NULL))
				return 0;
			p=p->next;
		}
	}
	return 1;
}

⌨️ 快捷键说明

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