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

📄 guyue30.cpp

📁 编译原理课设 有语法分析 词法分析 3地址输出 可惜的是不是四元式输出
💻 CPP
字号:
#include<stdio.h>                //预处理(头文件包含)
#include<string.h>
#include <conio.h>
#include<iostream.h>             
#define MaxiProgramNumber  888   //源程序最大字符的个数
#define MaxiWordLength     18    //标示符和关键字最长字符的个数
#define MaxiTokenNumer     118   //标识符能包含的最多的字符个数
/*………………………………………………………………………………………………*/
#define MaxiWordLength1     18 
#define MaxiTokenNumer1     118    
/*………………………………………………………………………………………………*/

char Ecode[MaxiTokenNumer1][MaxiWordLength1];
int Top=0;
int nID=1;                        //初始化
/*……………………………下面定义栈结构,栈中的元素是一个结构体………………*/
typedef struct
{
    int add;
	int next;
	char str[MaxiWordLength1];
}ADDL;                              //ADDL用于识别WHILE,DO

ADDL L[MaxiTokenNumer1];            //L为定义的结构体名
int nL=0;
int nadd=1;                         //初始化
/*………………………………输入串栈,栈中元素为结构体……………………………*/
typedef struct
{
 int ID;
 char b[MaxiWordLength];
}link;

link Token[MaxiTokenNumer];
link Token2[MaxiTokenNumer];
int nTokenNumer=1;                  //标志位置
char a[MaxiProgramNumber];          //数组用于装入源程序
int nLength=0;                      //用于指向数组中的元素 
/*……………………………函数声明(词法分析部分用到的函数)………………………*/

void GetProgram();                  //把源程序装入数组a
char GetChr();                      //将数组a中的元素读出
int Judge(char& chr);               //用于判断'\0'            
int IsLetter(char c);               //用于判断是否为字母
void Input(char* p,char c,int& nx); //标识符或关键字进入指针p指向的数组第nx+1个元素
void Save(char* word,int x);        //将关键字或标志符或算符装入Token
void Getcode();

/*……………………………函数声明(语法分析部分用到的函数)………………………*/
void Pop();                         //出栈
void InputS();
void InputE1();
void InputE2();
void InputE3();
void InputA();
int  firstset();                 
int  panduanSEA();                     //识别非终结符
int  EStrcmp();
/*…………………………………………词法分析部分……………………………………*/
int Wordanalyze()
{
  int jieshu=0;                     //词法分析没有结束    
  char chr;
  cout<<"*********************请输入一段源程序(以#为结束标志):************************"<<endl<<endl
	  <<"************************计算机0305班30号 张古月******************************"<<endl<<endl;
  GetProgram();                     //把源程序装入数组a
  int x;
  char word[MaxiWordLength];        //声明临时数组
  while((chr=GetChr())!='\0')      
  {
	  if(!(Judge(chr)))
	  {
		  break;
	  }                             //跳过空格和回车取元素  
	  x=0;
	  word[x]='\0';                 //清空       

	  if(IsLetter(chr))            
	  { jieshu=1;
	     while(IsLetter(chr))
		 {
		   Input(word,chr,x);       //是字符就将其装入数组word
           chr=GetChr();           
		    }
		 if(chr=='>' || chr=='='||chr=='<')
			 nLength=nLength-1;     //指向算符

		 word[x]='\0';
         Save(word,x);              //将关键字或标志符或算符装入Token
	  }
	  else if(chr=='>')             //将'>'装入Token
	  {
		  Input(word,chr,x);

		  word[x]='\0';
		  
		  Save(word,x);
	  }
      else if(chr=='=')             //将'='装入Token
	  {
			  Input(word,chr,x);

			  word[x]='\0';

			  Save(word,x);
	  }
     else if(chr=='<')              //将'<'装入Token
	 {
			  Input(word,chr,x);

			  word[x]='\0';

			  Save(word,x);
	 }  
	 else
	 {
	     printf("输入出错!\n");       //出错处理

		jieshu=0;                       

		 return 0;
	 }
  }                                    //这个函数的作用是将输入符号放入Token
  if(jieshu==1)                         //词法分析结束
  {
      Getcode();

      printf("单词符号表为[<种别编码,单词属性>]:\n");

      for(int i=1;i<nTokenNumer;i++)   //输出词法分析结果
	  {
          printf("<");
    
		  printf("%d",Token[i].ID);
	
		  printf(",");
	
		  printf("%s",Token[i].b);

		  printf(">\n");

		  strcpy(Token2[i].b,Token[i].b);//将输入的符号拷贝在Token2中 
	  }
     for(int d=1;d<nTokenNumer;d++)      //将标识符号替换成id
	  {
		  if(Token[d].ID==6)
		  {
			  strcpy(Token[d].b,"id");
		  }
	  }

	  strcpy(Token[nTokenNumer].b,"#");

	  Token[nTokenNumer].ID=7;          //'#'的种别编码为7

	  return 1;
  }
 getch();
}

void GetProgram()                       //把源程序装入数组a
{
  char ch;

  while((ch=getchar())!='#')
  {
   if(nLength>=MaxiProgramNumber-2)
	   break;
   else
	   a[nLength++]=ch;  
  }
  a[nLength]='\0';
  
  nLength=0;
}

char GetChr()                          //将数组a中的元素读出
{
  if(nLength>=MaxiProgramNumber-1)
	  return '\0';
  else
	  return a[nLength++];
}

int Judge(char& chr)                   //用于判断'\0',返回值为0时为'\0'
{
  while(chr==10 || chr==32)            //当chr为空格和换行时
  {
    chr=GetChr();
	
	if(chr=='\0')
	{
		return 0;
	}
  }
  return 1;
}

int IsLetter(char c)                  //用于判断是否为字母
{
  if(c>='a' && c<='z' || c>='A' && c<='Z' )
		return 1;
	else
		return 0;
}

void Input(char* p,char c,int& nx)   //标识符或关键字进入指针p指向的数组第nx+1个元素
{
  if(nx<MaxiWordLength-1)
  {
	  p[nx]=c;
  
	  nx++;
  }
}

void Save(char* p,int x)              //将关键字或标志符或算符装入Token
{
   for(int i=0;i<=x;i++)

	   Token[nTokenNumer].b[i]=p[i];

   nTokenNumer=nTokenNumer+1;
}
/*…………………………为不同的输入符号赋予不同的种别编码……………………*/
void Getcode()
{
  for(int i=1;i<nTokenNumer;i++)
  {
    if(strcmp(Token[i].b,"while\0")==0)
		Token[i].ID=1;
	else if(strcmp(Token[i].b,"do\0")==0)
		Token[i].ID=2;
    else if(strcmp(Token[i].b,">\0")==0)
		Token[i].ID=3;
	else if(strcmp(Token[i].b,"=\0")==0)
		Token[i].ID=4;
	else if(strcmp(Token[i].b,"<\0")==0)
        Token[i].ID=5;
	else 
	    Token[i].ID=6;
  }
}
/*………………………………………语法分析过程……………………………………*/
int ExpressionAnalyse()               //语法分析
{
 printf("\n语法分析得出:\n");
	
 strcpy(Ecode[Top++],"#");            //将#压栈

 strcpy(Ecode[Top++],"S");            //将S压栈

 int FLAG=1;                          //语法分析未结束标志
 
 while(FLAG)
 {
	 int f1=0;
	 f1=panduanSEA();
 
	 if(f1==1)
	 {
		  cout<<"  S->while E do A"<<endl; 
		  InputS();
	 }
	 else if(f1==2)
	 {   int f3=0;
		 f3=firstset();
		 if(f3==1)
		 {
		  cout<<"  E->id>id"<<endl;
		  InputE1();
		 }
         else if(f3==2)
         {
		  cout<<"  E->id=id\n"<<endl;
		  InputE2();
		 }
		 else 
		 {
		  cout<<"  E->id<id"<<endl;
		  InputE3();
		 }
	 }
	 else if(f1==3)
	 {
		 cout<<"  A->id=id"<<endl;
		 InputA();
	 }
	 else 
	 {
		 int f2=0;
		 f2=EStrcmp();
		 if(f2==1)                        //识别出关键字
		 {  
			Pop();
			nID=nID+1;
		 }
		 else if(f2==3)                   //识别出#,分析结束
		 {
		  cout<<endl<<"语法正确!"<<endl;
		  FLAG=0;
		  return 1;
		 }
		 else
		 {   
		  cout<<endl<<"语法出错啦!"<<endl;
		  FLAG=0;
		  return 0;
		 }
	 }
 }
 getch();
}

void InputS()                             //压栈        
{
	Pop();
	strcpy(Ecode[Top++],"A");
	strcpy(Ecode[Top++],"do");
	strcpy(Ecode[Top++],"E");
	strcpy(Ecode[Top++],"while");
}

void InputE1()                             //压栈 
{
    Pop();
	strcpy(Ecode[Top++],"id");
	strcpy(Ecode[Top++],">");
	strcpy(Ecode[Top++],"id");
}

void InputE2()                             //压栈 
{
    Pop();
	strcpy(Ecode[Top++],"id");
	strcpy(Ecode[Top++],"=");
	strcpy(Ecode[Top++],"id");
}

void InputE3()                             //压栈 
{
    Pop();
	strcpy(Ecode[Top++],"id");
	strcpy(Ecode[Top++],"<");
	strcpy(Ecode[Top++],"id");
}

void InputA()                             //压栈 
{
    Pop();
	strcpy(Ecode[Top++],"id");
	strcpy(Ecode[Top++],"=");
	strcpy(Ecode[Top++],"id");
}

void Pop()                               //出栈操作
{
    Top=Top-1;
}

int firstset()
{  
	if(strcmp(Token2[3].b,">")==0)
		return 1;     
    if(strcmp(Token2[3].b,"=")==0)
		return 2; 
	if(strcmp(Token2[3].b,"<")==0)
		return 3;   
}
int panduanSEA()                           //识别非终结符
{
    if(strcmp(Ecode[Top-1],"S")==0)
		return 1;
	else if(strcmp(Ecode[Top-1],"E")==0)
		return 2;
	else if(strcmp(Ecode[Top-1],"A")==0)
		return 3;
	else
		return 4;
}

int EStrcmp()                           //识别while和do关键字
{
           if(strcmp(Ecode[Top-1],"#")==0)
		   {
		              if(strcmp(Token[nID].b,"#")==0)	
			                return 3;
		   }
		   else if(strcmp(Ecode[Top-1],Token[nID].b)==0)
		   {
		                   if(strcmp(Ecode[Top-1],"while")==0)
						   {
							    L[nL].add=nadd++;
			                    L[nL].next=nadd++;
			                    strcpy(L[nL].str ,"while");
			                    nL++;
						   }
		                   if(strcmp(Ecode[Top-1],"do")==0)
						   {
							     L[nL].add=nadd++;
								 L[nL].next=L[nL-1].add;
                                 strcpy(L[nL].str ,"do");
			                     nL++;
						   }
						   return 1;
		   }
	       else
	           	return 0;
	cout<<Token[2].b<<endl;
}
/*……………………………………语义分析……………………………………*/
 void main()
 {
	 cout<<"****************************编译原理课程设计:*********************************"<<endl<<endl;
	 cout<<"*************while语句的翻译分析程序,采用LL(1)法,输出三地址:*************"<<endl<<endl;
	 cout<<"***************************程序所用的文法为:*********************************"<<endl;
	 cout<<"  S->while E do A"<<endl;                   
	 cout<<"  E->id>id|E->id=id|E->id<id"<<endl;
	 cout<<"  A->id=id"<<endl;
     cout<<" (id代表标识符)"<<endl;
	 
	 if(Wordanalyze())              //词法分析成功
	 {
		if(ExpressionAnalyse())     //语法分析也成功
		{
		 int i;
		 L[nL].add=nadd;
		 for(i=0;i<nL;i++)
		 {
		  if(strcmp(L[i].str,"while")==0)
		  {  cout<<endl;
			 cout<<"正确的语义输出为:"<<endl;
			 cout<<"L0:  if "<<Token2[2].b<<" > "<<Token2[4].b<<"  goto L2"<<endl;
			 cout<<"L1:  if not goto L4"<<endl;
		  }
		  else 
		  {
			 cout<<"L2:  "<<Token2[6].b<<":="<<Token2[8].b<<endl;
             cout<<"L3:  "<<"goto L0"<<endl;
             cout<<"L4:  "<<endl;
		  }
		 }
		}
	 }
}


⌨️ 快捷键说明

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