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

📄 22.txt

📁 编译原理课程设计。DOWHILE语句的翻译,递归下降法
💻 TXT
字号:
#include"stdafx.h"
#include"stdio.h"
#include<string.h>
#include"conio.h"  //要使用函数getch
#include"stdlib.h" //要使用函数itoa
#include<iostream>
using namespace std;

char shuru[80],token[8]; //shuru数组是保存字符串;
char ch;
int syn,p,m,n,sum,kk,q,tx=0; //sum保存字符数字的值;syn是字符类型标识
char *Guanjz[2]={"while","do"}; //关键字集合
struct{
   char result[8];
   char ag1[8];
   char op[8];
   char ag2[8];
   }Sandz[20];//保存4元式
void scaner(); //词法分析程序声明;每次调用此函数,会得到一个单词
int lrparser();//语法分析声明
int G();
char *E();
char *expression();//表达式的分析,加减法运算的分析
char *factor();//负责取token并进行下一个的词法分析
char *newtemp();
void emit(char *result,char *ag1,char *op,char *ag2);//给结构体变量Sandz[]赋值

int main()  //主函数
{int j;
 p=0;
 cout<<"输入字符串:"<<endl;
 do
 {ch=getchar();  //获取输入字符串,以#作结束符,并且#是数组shuru[]的最后一个字符
  shuru[p++]=ch;
 }while(ch!='#');
 p=0;
 kk=0;
 q=0;
 scaner(); //对输入的字符串进行词法分析;获取一个单词
 lrparser(); //对输入的单词进行语法分析
 if(q>19) //结构体数组Sandz[]大小为20
   cout<<"语法分析太长!"<<endl;
 else 
   for(j=0;j<q-1;j++)
     cout<<j<<":  "<<Sandz[j].result<<"="<<Sandz[j].ag1<<Sandz[j].op<<Sandz[j].ag2<<endl;//将语义分析过程打印成四元式格式
 cout<<j<<":  "<<Sandz[j].op<<" "<<Sandz[j].ag1<<" "<<Sandz[j].ag2<<" "<<Sandz[j].result<<endl;
 cin>>ch;
 return 0;
}

void scaner()
{m=0;
 sum=0;
 for(n=0;n<8;n++)
	 token[n]=NULL;   //将token清空
 ch=shuru[p++];       //获取缓冲区一个字符
 while(ch==' ') 
	 ch=shuru[p++];   //是空格时,忽略,获取下一个
 if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z') //是字母时
  {while(ch>='a'&&ch<='z' || ch>='A'&&ch<='Z' || ch>='0'&&ch<='9')
    { token[m++]=ch; //字符保存到TOKEN
      ch=shuru[p++]; //获取下一个字符
    }
   token[m++]='\0';//TOKEN得到了单词
   p--;//指针回到不满足条件的那个字符
   syn=10;//TOKEN中保存的字符类型是10,即变量或关键字
   for(n=0;n<2;n++)
    if(strcmp(token,Guanjz[n])==0) //与关键字集合比较,若相同,则该TOKEN保存的类型为对应的关键字
     {syn=n+1;break;}
  }
 else
  if(ch>='0'&&ch<='9') //是数字时,保存到num中,字符类型是11,即数字
  {while(ch>='0'&&ch<='9')
   {token[m++]=ch;
    ch=shuru[p++];
   }
   token[m++]='\0';
   p--;
   syn=11;
  }
  else
   switch(ch) //是符号时
   {case'<':token[m++]=ch;  //是<或<=时
            ch=shuru[p++];
            if(ch=='=')
			{ syn=22;
              token[m++]=ch;
              token[m++]='\0';
			}
            else
			{ syn=20;
			  token[m++]='\0';
			  p--;
			}
            break;
    case'>':token[m++]=ch;  //是>或>=时
            ch=shuru[p++];
            if(ch=='=')
			{ syn=24;
              token[m++]=ch;
			  token[m++]='\0';
			}
            else
			{syn=23;
			 token[m++]='\0';
			 p--;
			}
            break;
    case'=':token[m++]=ch;  //是==或=时
            ch=shuru[p++];
            if(ch=='=')
			{ syn=17;
              token[m++]=ch;
			  token[m++]='\0';
			}
            else
			{ syn=18;
			  token[m++]='\0';
			  p--;
			}
            break;
	case'!':token[m++]=ch; //是!=或!时
		    ch=shuru[p++];
			if(ch=='=')
			{ syn=19;
			  token[m++];
			  token[m++]='\0';
			}
			else
			{ syn=9;
			  token[m++]='\0';
			  p--;
			}
			break;
    case'+':syn=13;token[m++]=ch;token[m++]='\0';break;
    case'-':syn=14;token[m++]=ch;token[m++]='\0';break;
    case'(':syn=27;token[m++]=ch;token[m++]='\0';break;
    case')':syn=28;token[m++]=ch;token[m++]='\0';break;
	case'{':syn=29;token[m++]=ch;token[m++]='\0';break;
	case'}':syn=30;token[m++]=ch;token[m++]='\0';break;
	case'#':syn=0; token[m++]=ch;token[m++]='\0';break;
	default:syn=-1;
    }
}


int lrparser() //语法分析
{ kk=0;//这里是用来判断是否出错
  if(syn==-1)
  { cout<<"输入了不能识别的符号,ERROR!"<<endl;}
  if(syn==2) //该单词为do
  {	scaner();
    if(syn!=29)//该单词不是{
	{cout<<"do后面没有{,ERROR!"<<endl;kk=1;}
	else 
	{scaner();
     G();//分析{后面的符号,如果不是变量、数字、运算符时,退出
	}
	if(syn!=30)
	{cout<<"do后面没有}结束,ERROR!"<<endl;kk=1;}
	else
	{scaner();
     if(syn==1)//该单词为while
	 { scaner();
	  if(syn!=27)//该单词不是(
	  {cout<<"while后面没有(,ERROR!"<<endl;kk=1;}
	  else
      { scaner();
        E();//分析(后面的符号,如果不是变量、数字、比较符时,退出
      }
	  if(syn!=28) //该单词不是)
	  {cout<<"while后面没有),ERROR!"<<endl;kk=1;}
	  if(kk!=1)
	  {cout<<"分析成功!"<<endl;}
	 }
	 else
	  {cout<<"do后面没有while,ERROR!"<<endl;}
	}
  }
  else
  {cout<<"没有找到do,ERROR!"<<endl;}
  return 0;
}

int G() //赋值运算
{ char tt[8],eplace[8];
 
  if(syn==10)  //输入类型是变量
  { strcpy(tt,token); //将变量名复制到tt中
    scaner(); 
    if(syn==18) //如果输入类型是赋值号=
	{ scaner(); 
      strcpy(eplace,expression());//将赋值号后面的值放入eplace中,该值用t1,t2。。。表示
      emit(tt,eplace,"","");//此步骤写成4元式
   
	}
    else
	{ cout<<"没有赋值"<<endl;kk=1;}
  }
  else
  { cout<<"输入的变量错误"<<endl;kk=1;}
  return 0;
  }

char *expression() //表达式的值,算加减法
{char *result,*ag1,*ag2,*op;//tt保存符号
 result=new char;
 ag1=new char;
 ag2=new char;
 op=new char;
 if(syn==10||syn==11)//如果得到的是变量或数字,将因数放入ag1中
  strcpy(ag1,factor());
 while(syn==13 || syn==14) //是+或-号时
 { if (syn==13)
     strcpy(op,"+");
   else
	 strcpy(op,"-");
   scaner();
   strcpy(ag2,factor());//假设第二个操作数是变量或数字
   strcpy(result,newtemp());//将结果记录为t1、t2、t3、....
   emit(result,ag1,op,ag2);//保存为4元式
  }
 return(result);
}

char *factor() //取单词并进行下一个的词法分析
{ char *value;
  value=new char;
  strcpy(value,token);//将单词保存到value中,再扫描下个单词
  scaner();
  return(value);//将得到的单词返回
}

char *newtemp()//表达式的值
{ tx++;
  char lx;
  lx=tx+'0';
  char m[8];
  m[0]='t';
  m[1]=lx;
  m[2]='\0';
  return(m);
}

void emit(char *result,char *ag1,char *op,char *ag2)
{strcpy(Sandz[q].result,result);
 strcpy(Sandz[q].ag1,ag1);
 strcpy(Sandz[q].op,op);
 strcpy(Sandz[q].ag2,ag2);
 q++;
}

char *E()
{char wei[20];
 if(syn==10)
 { strcpy(wei,factor());
   if(syn<=24 && syn>=17)
   {strcat(wei,token);//将比较符放到数组wei中;
    scaner();     //扫描下一个单词;
    if(syn==10||syn==11)
	{strcat(wei,token);//将变量或数字放到数组wei中;
	 emit("1",wei,"if","goto");//":  if "<<wei<<" goto 1"<<endl;
	 scaner();
	}
    else
      {cout<<"条件判断表达式有错误,ERROR!"<<endl;kk=1;}
   }
   else
      {cout<<"条件判断表达式有错误,ERROR!"<<endl;kk=1;}
  }
 else
  {cout<<"条件判断表达式有错误,ERROR!"<<endl;kk=1;}
 return wei;
}

⌨️ 快捷键说明

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