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

📄 compile.cpp

📁 简单整型表达式文法按递归下降方式设计其编译程序
💻 CPP
字号:
#include<iostream.h>
#include<string.h>
#include<stdio.h>
#include"compile.h"
#define MAX_pcodeSIZE 200
#define MAX_tableSIZE 30
#define MAX_RUNSTR 300
enum SYM{plus,minus,times,div,lparen,rparen,equal,number,chid,endflags}; //定义单词的类别
struct allvarble     //定义全程变量
{ 
	enum SYM sym;  //类别
	int num;       //值
} Allvar; 
struct table    //字母表
{
	char ident; //字母
	int value;  //字母的值
}identable[MAX_tableSIZE]; 
struct pl0       //定义存放栈式指令的pcode数组
{
	char *f;
	int l;
	int a;
} pcode[MAX_pcodeSIZE];

int s[MAX_RUNSTR];//定义运行栈
int t=0;   //运行栈顶指针
char buffer[200]; //存放读入的表达式串
int tx=0;     //buffer指针

void error(int errnum)      //出错处理
{
	switch(errnum)
	{
	   case 1:  cout<<"the compile program is error"<<endl;   
	   case 2:  cout<<"getsym error"<<endl;
	   case 3:  cout<<"no rparen match"<<endl;
	   case 4:  cout<<"other symbol!"<<endl;
	   case 5:  cout<<"can not open the file"<<endl;
	}
}

int pcode_pointer=0;   //指向最新生成的pcode代码的指针
void gen(char *p_f,int lev_value,int a_value)  //生成pcode目标代码
{
    pcode[pcode_pointer].f=p_f;
	pcode[pcode_pointer].l=lev_value;
	pcode[pcode_pointer].a=a_value;
	interpret();
    pcode_pointer++;
}

struct allvarble getsym()   //取单词
{  
	int sum=0;
	if(buffer[tx]=='\0')   //取到表达式的末尾
	{
		Allvar.sym=endflags;
		Allvar.num=-1;
	}
    else if(buffer[tx]>='a'&&buffer[tx]<='z') //读到的单词是字母
	{
	    Allvar.sym=chid;
		Allvar.num=buffer[tx];
		tx++;
	}
	else if(buffer[tx]=='+'||buffer[tx]=='-'||buffer[tx]=='*'||buffer[tx]=='/'||buffer[tx]=='('||buffer[tx]==')'||buffer[tx]=='=') //读到的单词是运算符
	{
       switch(buffer[tx])
	   {
     	case '+': Allvar.sym=plus;  break;
     	case '-': Allvar.sym=minus;  break;
	    case '*': Allvar.sym=times;  break;
     	case '/': Allvar.sym=div;   break;
     	case '(': Allvar.sym=lparen;  break;
    	case ')': Allvar.sym=rparen;  break;
    	case '=': Allvar.sym=equal;  break;
	   }
	   Allvar.num=-1;
	   tx++;
	}
	else if(buffer[tx]>='0'&&buffer[tx]<='9')  //读到的是数字
	{
	   while(buffer[tx]>='0'&&buffer[tx]<='9')
	   {
	     	sum=sum*10+(buffer[tx]-'0');
			tx++;
	   }
       Allvar.sym=number;
	   Allvar.num=sum;
	}	
	else error(2);
	return Allvar;
}
void expresion()  //表达式
{
	if(Allvar.sym==plus||Allvar.sym==minus)
	{
		enum SYM p_sym=Allvar.sym;
		getsym();
		term();
		if(p_sym==minus)   gen("opr",0,1);
	}
	else  term();
	while(Allvar.sym==plus||Allvar.sym==minus)
	{
		enum SYM q_sym=Allvar.sym;
		getsym();
		term();
		if(q_sym==plus)  gen("opr",0,2);
		else  gen("opr",0,3);
	}
}
void term()   //项
{
	factor();
	while(Allvar.sym==times||Allvar.sym==div)
	{
		enum SYM p_sym=Allvar.sym;
		getsym();
		factor();
		if(p_sym==times)
			gen("opr",0,4);
		else   gen("opr",0,5);
	}
}
int t_flags[10];    //t_flags记录查找到的字母的位置
int equal_flags=0; //记录等于号的数目,以对多个字母连续赋值
int tag=0;    //设置是否有等于号的标志 
void factor()      //因子
{
	int i=0;
	if(Allvar.sym==endflags) ;//表达式结束
	else                      //表达式没结束
	{
	   if(Allvar.sym!=chid)  //如果不是标识符
	   {
	    	if(Allvar.sym!=number)  //如果不是数字
			{
		    	if(Allvar.sym==lparen) 
				{
			    	getsym();
			    	expresion();
				    if(Allvar.sym==rparen)
					{
                      if(tag!=0)     //tag用来记录前面是否有等于号
					  {
					  	gen("sto",0,t_flags[equal_flags-1]); //给字母表的对应字母添值
                        equal_flags=equal_flags-1;
				    	tag--;
					  }
					  getsym();
					}
					else    error(3);
				}
				else error(4);
			}
			else  {gen("lit",0,Allvar.num);  getsym();}
	   }
	   else 
	   {		
		  struct allvarble t_allv=Allvar;
		  while(identable[i].ident!='#')
		  {
			  if(identable[i].ident==t_allv.num)  //
			  {     			    	
			      t_flags[equal_flags]=i; 
				  equal_flags++;
			      break;
			  }					
			  i++;
		  }
		  if(identable[i].ident=='#')   //没找到:则添字母表
		  { 
		   	 identable[i].ident=Allvar.num;// 
		     t_flags[equal_flags]=i;
			 equal_flags++;
		  }
	      getsym();
		  if(Allvar.sym==equal)
		  {
				tag++;
				getsym();
				expresion();
		  }
		  else
		  {	         
		       if(identable[i].value!=-1) { gen("lit",0,identable[i].value);  }//  待续?????
			   else   cout<<"the symbol is not defined"<<endl;					
		  }
	   }
	}
}

void block()    //语法分析程序
{
	getsym();   
	expresion();
}

void interpret()    //解释程序
{
	int a_value;
	char *p;
	p=pcode[pcode_pointer].f;   
	a_value=pcode[pcode_pointer].a;
    if(strcmp(p,"opr")==0)
		switch(a_value)
		{
		case 1: s[t]=-s[t];break;
		case 2: t=t-1;s[t]=s[t]+s[t+1];break;
		case 3: t=t-1;s[t]=s[t]-s[t+1];break;
		case 4: t=t-1;s[t]=s[t]*s[t+1];break;
		case 5: t=t-1;s[t]=s[t]/s[t+1];break;
		default : cout<<"not plus or minus or times or div!"<<endl;
		}
	else if(strcmp(p,"lit")==0)
		{
               t=t+1; s[t]=a_value;
		}
	else if(strcmp(p,"sto")==0)
		{
			identable[a_value].value=s[t];
		}
    else  cout<<"other pcode instruction!"<<endl;	
}

void main()
{
	int fx=0;
	char ch;
	FILE *fp;
	fp=fopen("test2.txt","r");
	if (fp==NULL)
      error(5);
    ch=fgetc(fp);
	while(ch!=EOF)
	{
		buffer[fx]=ch;
		ch=fgetc(fp);
		fx++;
	}
	buffer[fx]='\0';
	fclose(fp);
	
	for(int i=0;i<30;i++)  //初始化字母表
	{
		identable[i].ident='#';
		identable[i].value=-1;
	}

	int j=0;
	cout<<"the buffer is:"<<endl;
	while(buffer[j]!='\0')   //输出源表达式
	{
		cout<<buffer[j];
		j++;
	}
    cout<<endl;

	block();
	cout<<"the pcode is:"<<endl;	
	for(int p_xy=0;p_xy<pcode_pointer;p_xy++)  //输出pcode代码
	{
        cout<<endl;	
		cout<<pcode[p_xy].f<<"   "<<pcode[p_xy].l<<"    "<<pcode[p_xy].a<<endl;
	}
	cout<<"the result is: "<<s[t]<<endl;  //输出计算结果
}

⌨️ 快捷键说明

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