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

📄 赋值语句的翻译程序设计.cpp

📁 单词的词法分析程序设计
💻 CPP
字号:
#include<iostream>
#include<fstream>
#include<iomanip> //malloc.exit.realloc.strcmp.gets
#include"wordanalysis.h"//词法分析头文件
using namespace std;
#define OVERFLOW    -2
#define OK          1
#define ERROR      0
#define STACK_INIT_SIZE 50
#define STACK_INCREMENT  10
typedef int     Status;
#define n 10

int index,length;char *code[n][4];int error;ofstream rp;int m;
char *mid[n]={"t1","t2","t3","t4","t5","t6","t7","t8","t9","t10"};//四元式中的中间结果变量表明

/*赋值语句的文法为:
S->i:=E
E->E+E|E-E|E*E|E/E|(E)|i
*/

struct SElemType
{
	char id;//用于归约
	char *fword;//用于四元式
};//栈中元素的数据域为结构体

typedef struct{
SElemType *base;            //栈基址
SElemType *top;             //栈顶地址
int stacksize;
}SqStack;
Status initstack(SqStack &S)
//构造一个空栈
{
 S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
 if(!S.base)
 exit (OVERFLOW);//存储单元分配失败
 S.top=S.base;
 S.stacksize=STACK_INIT_SIZE;
 return OK;
}

Status push(SqStack &S,SElemType e)//插入新元素为栈顶元素
{
 if(S.top-S.base>=S.stacksize)
 {
  S.base=(SElemType *)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(char));
 if(!S.base)
  exit (OVERFLOW);
 S.top=S.base+S.stacksize;
 S.stacksize+=STACK_INCREMENT;
 }
 *(S.top)=e;
 S.top++;
 return OK;
}

Status pop(SqStack &S)//删除栈顶元素
{
 if(S.base==S.top)
  return ERROR;
  --S.top;
 return OK;
}

SElemType gettop(SqStack S)// 获得栈顶元素
{   
    SElemType e,ir;
	if(S.top==S.base)exit(0);
	else{ir=*(S.top-1);
		e.id=ir.id;e.fword=ir.fword;return e;}
	
}



void err(int e)//输出错误提示
{   if(e==1)
	cout<<"赋值语句错误,不完整"<<endl;
    if(e==2)
	cout<<"赋值语句语法错误,不符合产生式归约条件!"<<endl;
	exit(0);
}

char super(char a,char b)//运算符优先级.
{
   switch(a)
{
	case'+':
		switch(b)
		{ case'+':return '>';break;
		  case'-':return '>';break;
          case'*':return '<';break;
          case'/':return '<';break;
          case'(':return '<';break;
          case')':return '>';break;
		  case'=':return '>';break;
          case'#':return '>';break;
		  case';':return '>';break;//因为输入时以";"结尾,将;设为优先级最低
		  default:return '#';break;
		 }

    case'-':
	     switch(b)
		{ case'+':return '>';break;
		  case'-':return '>';break;
          case'*':return '<';break;
          case'/':return '<';break;
          case'(':return '<';break;
          case')':return '>';break;
          case'=':return '>';break;
          case'#':return '>';break;
          case';':return '>';break;
		  default:return '#';break;
         }
		
    case'*':
         switch(b)
		{ case'+':return '>';break;
		  case'-':return '>';break;
          case'*':return '>';break;
          case'/':return '>';break;
          case'(':return '<';break;
          case')':return '>';break;
          case'=':return '>';break;
          case'#':return '>';break;
          case';':return '>';break;
          default:return '#';break;
         }
	
    case'/':
          switch(b)
		{ case'+':return '>';break;
		  case'-':return '>';break;
          case'*':return '>';break;
          case'/':return '>';break;
          case'(':return '<';break;
          case')':return '>';break;
		  case'=':return '>';break;
          case'#':return '>';break;
          case';':return '>';break;
		  default:return '#';break;
		}
    case'(':
		  switch(b)
        { case'+':return '<';break;
		  case'-':return '<';break;
          case'*':return '<';break;
          case'/':return '<';break;
          case'(':return '<';break;
          case')':return '=';break;
          case'=':return '>';break;
		  case'#':return '>';break;
		  case';':return '>';break;
		  default:return '#';break;
	   	}

	case')':
		  switch(b)
		{ case'+':return '>';break;
		  case'-':return '>';break;
          case'*':return '>';break;
          case'/':return '>';break;
          case')':return '>';break;
          case'=':return '>';break;
          case'#':return '>';break;
		  case';':return '>';break;
		  default:return '#';break;
		}
    case'#':
         switch(b)
		{ case'+':return '<';break;
		  case'-':return '<';break;
          case'*':return '<';break;
          case'/':return '<';break;
          case'(':return '<';break;
		  case')':return '<';break;
          case'=':return '<';break;
          case';':return '>';break;
		  default:return '#';break;
		}
	case'=':
		switch(b)
		{ case'+':return '<';break;
		  case'-':return '<';break;
          case'*':return '<';break;
          case'/':return '<';break;
          case'(':return '<';break;
		  case')':return '<';break;
		  case'#':return '>';break;
		  case';':return '>';break;
		  default:return '#';break;
		}
      
		default:return '#';break;
}
}


char trans(char *cc)//将单词进行转换,以匹配文法
{   
	char t;char ch;
    ch=cc[0];
    if( ch==':'){ t='=';return t;}//将":="转化为'='进栈,以简化栈中id为字符型
	else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch==';')
	{return ch;}
	else return 'i';//输入的变量对应文法中的终结符'i'
}


int issuit(SElemType pro[])//是否为产生式右端
{   
	int q;
    if(pro[0].id=='i'&&pro[2].id=='E')q=1;
    else if(pro[0].id=='E'&&pro[2].id=='E') q=2;
	else{};
	if(pro[1].id=='='&&q==1)return 1;//i:=E时(前面已经将':='在栈中转化为'=')
    else if(pro[1].id=='+'&&q==2)return 2;//E+E时
    else if(pro[1].id=='-'&&q==2)return 3;//E-E时
	else if(pro[1].id=='*'&&q==2)return 4;//E*E时
	else if(pro[1].id=='/'&&q==2)return 5;//E/E时
	else if(pro[0].id=='('&&pro[1].id=='E'&&pro[2].id==')')return 6;//(E)时
	else return 0;
}

int gram(SqStack s)//语法分析(算符优先法)
{   
  int count=0;SElemType po[3];char getpre,ch;int keep;
  getpre='#';//为第一个运算符设置优先级对比对象
  index=0;SElemType nod,save;int ii=0;
  ch=trans(word[index]);keep=index;index++;
  do{
	  if(ch=='i')//运算对象终结符'i'移进
	  { cout<<"动作:移进"<<endl;
		nod.fword=word[keep];nod.id=ch;
		push(s,nod);ch=trans(word[index]);keep=index;index++;count++;
	    if(count>1)//除了第一个产生式(此时count==1)的i不归约,其他的i由于优先级最高,进栈后立即归约
		{   cout<<"动作:归约(7)"<<endl;
			nod.id='E';nod.fword=gettop(s).fword;
			pop(s);push(s,nod);}else{};
	  }
      else//为运算符时
	 {
	  if(super(getpre,ch)=='<'||super(getpre,ch)=='=')//与前一个运算符对比优先级,比前者高则移进
	  {   nod.id=ch;nod.fword=word[keep];
		  push(s,nod);getpre=ch;ch=trans(word[index]);keep=index;index++;count++;
		  cout<<"动作:移进"<<endl;
	  }
	  else if(super(getpre,ch)=='>')//与前一个运算符对比,优先级要低,此时应该归约
	  {      
		      
		   if(count<3){error=1;return 0;}//归约时至少应该有三个字符(第一个产生式除外),否则错误
			  else
			  {
		   	     for(int i=2;i>=0;i--)//三个字符出栈进行归约
				 { 
                   po[i].fword=gettop(s).fword;
				   po[i].id=gettop(s).id;
			       pop(s);
				 }  
			     
			   if(count>3)
			   {
               if(issuit(po)==1||issuit(po)==2||issuit(po)==3||issuit(po)==4||issuit(po)==5||issuit(po)==6) 
			   {    if(issuit(po)==6){nod.fword=po[1].fword;nod.id='E';//E->(E)归约不用记入四元式
			        cout<<"动作:归约("<<issuit(po)<<")"<<endl;}
				    else
					{
                    nod.fword=mid[ii];ii++;nod.id='E';//记入四元式中
			        code[m][0]=po[1].fword;
                    code[m][1]=po[0].fword;
                    code[m][2]=po[2].fword;
			        code[m][3]=nod.fword;
					m++;
					cout<<"动作:归约("<<issuit(po)<<")"<<endl;}
				    push(s,nod);count=count-2;
                    save=gettop(s);pop(s);getpre=gettop(s).id;push(s,save);//取出栈中第一个运算以准备比较优先级 
					
			   }
			   else{error=2;return 0;}
			  
			   }
			   
			  else if(count==3)//只剩三个字符时,为i=E(为方便归约,前面已将':='转化为'=')
			  {   
				  
			   if(issuit(po)==1) 
			   {   cout<<"动作:归约(1)"<<endl;
				   nod.fword=mid[ii];ii++;nod.id='S';//归约到开始符'S'
				   push(s,nod);count=count-2;
                   code[m][1]=po[2].fword;
                   code[m][2]="-";
			       code[m][3]=po[0].fword;
                   code[m][0]=po[1].fword;
                   save=gettop(s);pop(s);getpre=gettop(s).id;push(s,save);
				   
                }
			   else{error=2;return 0;}
                  
               
			  }
		 else {error=1;return 0;}
		}
        
			 
	  }
	  }
  }while(count!=1||gettop(s).id=='i');
  if(gettop(s).id!='S'){error=2;err(error);return 0;}
  else{cout<<"接受"<<endl;}//栈顶为开始符S,则成功
  pop(s);
  return 1;
}

void printcode(char *code[n][4],ofstream &ofile)//将四元式写入文件
{   int j;char jj;
	for(int i=0;i<=m;i++)
	{j=i+1;jj=j+'0';
    ofile.put('(');ofile.put(jj);ofile.put(')');
	ofile.put('(');
    ofile << code[i][0];
	ofile.put(','); 
    ofile << code[i][1];
	ofile.put(','); 
    ofile << code[i][2];
	ofile.put(',');
    ofile << code[i][3];
	ofile.put(')');
    ofile.put('\n');
	}
}

void print()//打印文法
{   
char a0='S';char a1='i';
char a2='E';char a3='+';
char a4='-';char a5='*';
char a6='/';char a7='(';
char a8=')';char a9[]=":=";

cout<<"赋值语句的文法为:"<<endl;
cout<<"(1)"<<a0<<"->"<<a1<<a9<<a2<<endl;
cout<<"(2)"<<a2<<"->"<<a2<<a3<<a2<<endl;
cout<<"(3)"<<a2<<"->"<<a2<<a4<<a2<<endl;
cout<<"(4)"<<a2<<"->"<<a2<<a5<<a2<<endl;
cout<<"(5)"<<a2<<"->"<<a2<<a6<<a2<<endl;
cout<<"(6)"<<a2<<"->"<<a7<<a2<<a8<<endl;
cout<<"(7)"<<a2<<"->"<<a1<<endl;


}

void readline()//获得输入的句子
{ char a;int le=0;
  a=getchar();
  while(a!='\n')
  {
  line[le]=a;
  a=getchar();
  le++;
  }

 linelen=le; 
 
}


int main()
{
  char resultfile[30];int t=0;
  SqStack stack;
  SElemType no;no.id='#';no.fword="nothing";
  print();
  initstack(stack);push(stack,no);
  cout<<"\n请输入需进行分析的赋值语句(';'结尾):"<<endl;
  readline();
  anlysis();
  cout<<"\n请输入分析后得到的输出文件名:";
  gets(resultfile);//将中间代码(四元式)保存入文件中
  rp.open(resultfile);
  cout<<"\n语法分析(算符优先分析法)……"<<endl;
  gram(stack);printcode(code,rp);
     if(error!=0)err(error);
     else{
     cout<<"\n对赋值语句语法分析成功!!生成的中间代码(四元式)已存入文件:"<<resultfile<<endl;
	 }
 
return 0;
}

⌨️ 快捷键说明

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