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

📄 布尔表达式的翻译.cpp

📁 布尔表达式的翻译
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std; 
#include <stdlib.h>
//全局变量定义 
//-------------------------------------------定义词法分析全局变量---------------------------
#define  BMaxlen  10000     
#define  KEY_No    12     
#define  WMaxlen  11        
#define  Sign_No  12     
#define  Limit_No  6       
#define  Maxtype  '5'       //定义单词的总类型共有5种 1关键字 2标志符 3shuzi 4运算符 5界符
#define  Longtype  '8'       //定义单词不合法且过长时的类型
#define  Errtype  '7'       //定义单词不合法但没超过长度的类型

//------------------------------------------词法分析函数声明及定义------------------------------
int getch();//用来从缓冲区中取一个字符
char getw();//从缓冲区中取一个单词
char Str[BMaxlen];//建立缓冲区
int  pStr=-1;     //用来表示从缓冲区取字母时的指针,定义为-1,为使以下的程序++pStr可以先指到缓冲区的第一个字母
char ch;        //用来表示从缓冲区中取出的一个字母
char *KEY[KEY_No]={{"if"},{"int"},{"for"},{"while"},{"do"},{"return"},{"break"},{"continue"},{"else"},{"and"},{"or"},{"not"}};
char *Sign[Sign_No]={{"+"},{"-"},{"*"},{"/"},{"%"},{"="},{"<"},{">="},{"<="},{"!="},{"=="},{">"}};
char *Limit[Limit_No]={{","},{";"},{"{"},{"}"},{"("},{")"}};
int  Fbuffer;//标志缓冲区中是否还有字母,如果没有的话,则Fbuffer的值为-1;如果还有的话,则其值为1
char Word[WMaxlen];//用来标识标识取出的单词
char CType;//用来标识得到的单词的类型
char Lasttype;//用来标识是其前面的单词的类型
char ty;//定义在调用取单词后取出的单词的类型

int getch()//用来从缓冲区中取一个字符,如果成功,则返回1,否则为-1
{ 
	ch=Str[++pStr];
	if (ch=='\0') return(-1);//当取出的字符是'\0',则表明缓冲区中已无字符,返回值为-1
	else return(1);
}

char getw()//从缓冲区中取一个单词
{
	bool flag=false;//用来表示取出的单词是否为关键词,如果是则flag的值为true,否则为false
	int k=-1;       //表示取出的字符放在单词数组的指针
	CType='0';      //预先定义的取出的单词的类型
	Lasttype='0';   //初始化先前的类型,此变量为判断正负数用
	while (ch<=32 && ch>0)//去掉不能显示的字符
		Fbuffer=getch();
	if (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z')//取出标识符或者是关键词
	{
		k=-1;
		while(true)//取出的单词长度不超过WMaxlen,如果超过,则其后的字符无效
		{  
			if((++k)<WMaxlen)//(++k)为了使取出的单词最长为WMaxlen
			{
				Word[k]=ch;
			}
			Fbuffer=getch();
			  
			//如果取出的当前的字符不是字母或是数字,则此次取单词结束
			if  (!(ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'||ch>='0' && ch<='9'))
				break; 
		}
		Word[++k]='\0';//以'\0'标识取出单词的结束,以方便后面的判断此单词是标识符还是关键词
		for (int i=0;i<KEY_No;i++)//用来判断取出的当前单词是不是关键词
			if (strcmp(Word,KEY[i])==0)
			{ 
				flag=true;
				break;
			}
			if (flag)  CType='1';//如果是关键词,则把此单词的类型定义为1型
			else CType='2';      //否则是标识符,其类型为2
	
	}       
	else if (ch>='0' && ch<='9')//判断是不是为整数
	{  
		Word[++k]=ch;
		Fbuffer=getch();
		while(true)//如果是数字,则一直接受,且定义它的类型为3
			if(ch>='0' && ch<='9')
			{
				Word[++k]=ch;
				Fbuffer=getch();
			}
			else  {CType='3';break;}//不是数字则跳出循环
			//如果以字母开头,且长度不超过WMaxlen,且下面跟有字母,则此整数非法,输出类型为8,在主程序中输出出错信息
			if (k<WMaxlen)
				if (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z')
				{
					Word[++k]=ch;
					Fbuffer=getch();
					//取这个非法整数的单词,其中可包含英文字母和数字
					while (ch>='a'&& ch<='z'|| ch>='A'&& ch<='Z'|| ch>='0' && ch<='9'||Fbuffer==-1)
						if (k<WMaxlen)
						{
							Word[++k]=ch;
							Fbuffer=getch();
						}
						else 
						{
							Fbuffer=getch();
							k++;
						}
						if (k>WMaxlen)//如果长度大于取出单词定义的最大长度,则返回类型为8,在主程序中打出出错信息
							CType=Longtype;
						else CType=Errtype;//否则返回类型7,在主程序出错,并明确写出此单词的具体内容
		}
			Word[++k]='\0';	
	}
	else if (ch=='+'||ch=='-'||ch=='*'||ch=='/')//取出是运算符号的单词
	{   
		Word[++k]=ch;
		if (ch=='+' || ch=='-')//如果是+号或者是-号,则还要判断是不是正负数
			if (Lasttype=='6')//判断其取出的当前字母的前一个单词是6号类型的,即是<、>、<=、>=、==、=时则可判断现在取出的是整数
			{	
			
				Fbuffer=getch();
				while(ch>='0' && ch<='9')//取出整数
				{
					Word[++k]=ch;
					Fbuffer=getch();
				}
				CType='3';//如果正负整数,则直接返回类型为3,则表示此单词为整数
				return(CType);
         
			}
			else Fbuffer=getch();//如果不是整数,则定义当前取出的单词是运算符,定义此类型为4
			Word[++k]='\0';
			CType='y';
	}
	else if (ch=='>'||ch=='<'||ch=='='||ch=='!')//取出运算符的另几类,即<、<=、>、>=、==、=、!=
	{    
		Word[++k]=ch;Fbuffer=getch();
		if( ch=='=')//判断是不是<=、>=、==、!=
		{ 
			Word[++k]=ch;
			Fbuffer=getch();
		}
		Word[++k]='\0';
		for (int i=0;i<Sign_No;i++)//判断取出的单词是不是运算符
			if (strcmp(Sign[i],Word)==0) 
			{ 
				flag=true;
				break;
			}
			if (flag)  CType='4';
			
			Lasttype='6';
		
	} 
	else if (ch==','||ch==';'||ch=='{'||ch=='}'||ch=='('||ch==')')//判断当前取出的单词是不是界符,如果是界符,则定义其类型为5
	{     
		CType='5';
		Word[++k]=ch;
		Word[++k]='\0';
		Fbuffer=getch();
	}

	return(CType);
}
//---------------------------------词法分析变量及函数定义结束-----------------------



//---------------------------------声明输出四元式用到的全局变量---------------------------
struct token{
	 char value[10];//dan ci
	int  pose;//wei zhi
	char type;//lei xin 
};
struct token token_list[20];
struct token pp(char * word,int pos1,char ty)
{
	struct token itoken;
	itoken.pose=pos1;
	itoken.type =ty;
	strcpy(itoken.value,word);

	return itoken;
}
//--------------------------------------------------------------------------------------


//----------------------------------定义语法分析全局变量-------------------------------------------
#define MAX 100 
char analyzed_sentence[MAX]=""; 
char s[MAX]="";
char stack[MAX]=""; 
char top; 
char *temp; 
char identified[MAX]=""; 
int n=0; 
char par_list[10];
//定义LL(1)分析表 
char Vn_array[] = "EATBFGSMQ"; 
char Vt_array[] = "+*!IDO()#"; 
char  *LL1_array[][9] = { 
   {" ", " ", "TA", "TA", "TA", " ","TA"," "," "}, 
   {"+TA", " ", " ", " ", " ", " ", " ", "u", "u"}, 
   {" ", " ", "FB", "FB", "FB", " ","FB"," ", " "}, 
   {"u", "*FB", " ", " ", " ", " ", " ", "u", "u"}, 
   {" ", " ", "!G", "G", "G", " ","G"," ", " "} ,
   {" ", " ", " ", "S", "S", " ", "(E)", " ", " "},
   {" ", " ", " ", "MQ", "MQ", " ", " ", " ", " "},
   {" ", " ", " ", "I", "D", " ", " ", " ", " "},
   {"u", "u", " ", " ", " ", "OM", " ", "u", "u"}
}; 
//----------------------------------语法分析函数声明及定义 ---------------------------------------------
void input(); //输入字符流
void init_stack(); //初始化堆栈
int ll1_analyzing(); //主分析程序
void ll1array_push(char); //将得到的产生式字符串压入堆栈中
int is_Vt(); //判断栈顶符号是否终结符号
int is_ll1array(char); //分析当前栈和流首符号能否在LL1表中找到产生式
int Vn_index(); //获得栈顶字符在非终结符集中的位置
int Vt_index(char); //获得输入流首元素在终结符集中的位置
void pop(); //将堆栈中首符号弹出 修改栈顶符号
void push(char); //将字符压入堆栈 修改栈顶符号
void reverse(); //将LL1表中的产生式字符串倒序 该函数定义有错误
int printerror(); 
void input() 
{ 
   strcpy(analyzed_sentence,par_list);
} 

void init_stack() 
{ 
   stack[0] = '#'; 
   stack[1] = Vn_array[0]; //开始符进栈 
   cout << stack[1] << "->"; 
} 

int ll1_analyzing() 
{ 
   top = stack[1]; 
   int error; 
   for (int i=0;i<=strlen(analyzed_sentence);i++) { 
      int test; 
      test = is_Vt(); //判断当前堆栈首字符是否是终结符号
      if (1 == test) { 
         if (top == analyzed_sentence[i]) { //如果堆栈和输入流首字符都是一样的终结符号
            identified[n++] = top; 
            pop(); //弹出栈顶字符
            continue; 
         } 
         else { 
            printerror(); 
            break; 
         } 
      } 
      else if ('#' == top) {   //结束,将最终的表达式打印出来,除了'#' 
         for (int p=0;p<strlen(analyzed_sentence)-1;p++) { 
               printf("%c", analyzed_sentence[p]); 
            } 
               break; 
         } 
      else { //当前堆栈首字符是非终结符号
         do  { 
               int judge=0; 
               judge = is_ll1array(analyzed_sentence[i]); //判断LL1表中对应项是否有产生式
               if (judge == 1) { 
                  if (1 == is_Vt()) {     //假设有符号不匹配,出错 “好象着段用不着”
                     error=printerror(); 
					 
                     break; 
                  } 
				  
                  ll1array_push(analyzed_sentence[i]); 
               } 
               else { 
                  error = printerror(); 
                  break; 
               } 
                               
            } 
            while (top != analyzed_sentence[i]); 
            if (error == 1) 
               break; 
            identified[n++] = top; 
            if (top != '#') 
               pop(); 
      } 
    
   } 
   if(error==1)return 0;
   else
   {cout << "这是一句合法的句子!" <<endl;
   return 1;}
} 

void ll1array_push(char currentchar) 
{ 
   int i,j; 
   i=Vn_index();  //求栈顶元素在Vn数组里面的下标 
   j=Vt_index(currentchar);  //求当前处理的符号在Vt数组里面的下标 
   temp=LL1_array[i][j]; 
   reverse(); 
   pop(); 
   int k; 
   for(k=0;k<strlen(temp);k++) 
   { 
      push(temp[k]); 
   } 
   printf("%s", identified); 
   for (int m=strlen(stack)-1;m>0;m--) 
      cout << stack[m] ; 
   cout << "->"; 
   if (top == 'u') 
      pop(); 
} 

void pop() 
{ 
   int topnum; 
   topnum = strlen(stack)-1; 
   stack[topnum] = '\0'; 
   top = stack[topnum-1]; 
} 

void push(char element) 
{ 
   int topnum; 
   topnum = strlen(stack); 
   stack[topnum] = element; 
   top = element; 
} 

int is_Vt() 
{ 
   int i; 
   int hit=0; 
   for (i=0;i<strlen(Vt_array);i++) { 
      if(top == Vt_array[i]) 
         hit = 1; 
   } 
   if (top == '#') 
      hit = 0; 
   if (hit == 1) 
      return 1; 
   else 
      return -1; 
} 
    
int is_ll1array(char currentchar) 
{ 
   int i,j; 
   i=Vn_index();  //求栈顶元素在Vn数组里面的下标 
   j=Vt_index(currentchar);      //求当前处理的符号在Vt数组里面的下标 
   if (LL1_array[i][j] == " ") { 
      return -1; 
   } 
   else 
      return 1; 

} 


int Vn_index() 
{ 
   for(int i=0;i<strlen(Vn_array);i++) { 
      if (top == Vn_array[i]) 
         return i;       
   } 
   return -1; 
} 

int Vt_index(char index_array) 
{ 
   for(int i=0;i<strlen(Vt_array);i++) { 
      if (index_array == Vt_array[i]) 
         return i; 
   } 
   return -1; 
} 

void reverse() //逆序处理 
{ 
 
   strcpy(s, temp); 
   int i,j; 
   char tem; 
   i=0; 
   while (s[i] != '\0') 
      ++i; 
   --i; 
   if (s[i] == '\n') 
      --i; 
   j=0; 
   while (j<i) 
   { 
      tem = s[j]; 

⌨️ 快捷键说明

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