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

📄 编译原理.cpp

📁 编译原理课程设计 布尔表达式的实现与设计过程
💻 CPP
字号:
#include<iostream>
#include<setjmp.h>
#include<sstream>

   
#define EXP_LEN    100                       //定义输入字符缓冲区的长度
/*------------出错代码的宏定义--------------*/
#define INVALID_CHAR_TAIL 0          //表达式后跟有非法字符
#define CHAR_AFTER_RIGHT 1           //右括号后连接非法字符
#define LEFT_AFTER_NUM  2            //数字后非法直接连接左括号
#define INVALID_CHAR_IN  3           //表达式中含有非法字符
#define NO_RIGHT   4                 //缺少右括号
#define EMPTY_BRACKET  5             //括号内无表达式
#define UNEXPECTED_END  6  
#define LIANXU	7          //预期外的算术表达式结束
using namespace std;
const string ErrCodeStr[]=                   //表达式出错信息
{
 "表达式后跟有非法字符!",
 "右括号后连接非法字符!",
 "常量后非法直接连接左括号!",
 "表达式中含有非法字符!",
 "缺少右括号!",
 "括号内无表达式或表达式不完整!",
 "表达式非法结束或表达式不完整!",
 "表达式中有连续字符!"
};
static char expr[EXP_LEN],opt;                 //算术表达式输入字符缓冲区
static int pos,line=0;                         //字符指示器标志:用来保存正在分析的字符的位置
static jmp_buf errjb;						   //出错跳转缓冲器
//********以下是函数声明*********
//执行或运算。
bool E_Or(); 

//执行与运算。
bool T_And(); 

//执行非运算。
bool F_Not();

//判断输入符号是不是布尔
int Isbool(char ch);

//出错处理函数,可以指出错误位置,出错信息。
void Error(int ErrCode);




//主函数
int main()
{
 bool ans;                                   //保存算术表达式的计算结果
 char quit[1]={0};
 bool esc=false;							//是否退出计算
MENU:                                        //主菜单显示。

	cout<<" * ** ** ** ** ** ** ** ** ** ** *"<<endl;
	cout<<"*                                *"<<endl;
	cout<<"*    请输入选择项(1或2):      *"<<endl;
	cout<<"*                                *"<<endl;
	cout<<"*    1:输入布尔表达式           *"<<endl;
	cout<<"*                                *"<<endl;
	cout<<"*    2:程序退出。               *"<<endl;
	cout<<"*                                *"<<endl;
	cout<<" * ** ** ** ** ** ** ** ** ** ** *"<<endl;
	

while(1)
{
	cin>>opt;
	if(opt=='1')
	{
	
		//在此设定一个跳转目标,如果本程序的其他函数调用longjmp,
		//执行指令就跳转到这里,从这里继续执行。
		OPT:if(setjmp(errjb)==0)                       //如果没有错误
			{
				pos=0;									//初始化字符指示器为0,即指向输入字符串的第一个字符。
				cout<<"提示:"<<endl;
				cout<<"	运算符:与(&),或(^),非(!).	常量:true(t或T),false(f或F)."<<endl<<endl;
				cout<<"请输入一个布尔表达式:"<<endl;
				cin>>expr;                               //接受表达式。
				ans=E_Or();
				//此时,程序认为对表达式的语法分析已经完毕,下面判断出错的原因:
				//如果表达式中的某个右括号后直接跟着字符,则报错。
				if(expr[pos-1]==')'&&expr[pos]!='\0')
				Error(CHAR_AFTER_RIGHT);
				//如果表达式中的右括号后直接跟着左括号,
				//则报错
				if(expr[pos]=='(')
				Error(LEFT_AFTER_NUM);
				//如果结尾有其他非法字符
				if(expr[pos]!='\0')
				Error(INVALID_CHAR_TAIL);
				cout<<"计算得出表达式的值为:"<<boolalpha<<ans<<endl;
			}
			else
			{
				//setjmp(errjb)!=0的情况:
				cout<<"请重新输入!"<<endl;
			}
			cout<<"表达式处理完毕!"<<endl;
			cout<<"1:继续计算:"<<endl;
			cout<<"2:回到主选单:"<<endl;
			
			cout<<endl;
			//while(1){
			cin>>quit;
			//if(sizeof(quit)==1){

				if(quit[0]=='1')goto OPT;			
			else	/*if(quit[0]=='2')*/goto MENU;//返回主菜单。
			//else cout<<"请重新选择:"<<endl;}
			//继续输入表达式运算。
	
	}
	if(opt=='2')	exit(0);//退出程序。
	else
		cout<<"输入有误,请从新输入!"<<endl;
}
return 0;
}
 

bool E_Or()
{
	bool rtn=T_And();              //计算“或”表达式的左元
	while(expr[pos]=='^')
	{
		char op=expr[pos++];             //取字符缓冲区中当前位置的符号到op
		bool opr2=T_And();            //计算“或”算术表达式的右元
		//计算求值
		if(op=='^')                     //如果是"|"号
			rtn|=opr2;                     //则用或计算
	}
	return rtn;
}
 
bool T_And()
{
	bool rtn=F_Not();          //计算“与”表达式的左元
	while(expr[pos]=='&')
	{
		char op=expr[pos++];        //取字符缓冲区中当前位置的符号到op
		bool opr2=F_Not();      //计算与布尔表达式的右元
		//计算求值
		if(op=='&')                       //如果是"&"号
			rtn&=opr2;                     //则用"与"计算
	}
	return rtn;
}
 

bool F_Not()
{
	bool rtn;                            //声明存储返回值的变量
	//用产生式F->!F推导:
	if(expr[pos]=='!')
	{
		pos++;
		rtn=!F_Not();
		return rtn;
	}
	//用产生式F->(E)推导:
	if(expr[pos]=='(')              //如果字符缓冲区当前位置的符号是"("
	{
		pos++;                         //则指示器加一指向下一个符号
		rtn=E_Or();           //调用产生式“E -> T^E | T&E | T”的分析函数
		if(expr[pos++]!=')')         //如果没有与"("匹配的")"
		Error(NO_RIGHT);        //则产生错误
		return rtn;
	} 
	if(Isbool(expr[pos])!=-1)        //如果字符缓冲区中当前位置的布尔值
	{int i=0;
		//则用产生式F -> i推导
		//把字符缓冲区中当前位置的字符串转换为整数
		//改变指示器的值,跳过字符缓冲区的数字部分,找到下一个输入字符。
	   while(Isbool(expr[pos])!=-1){

	  //if(Isbool(expr[pos])==1)
			while(Isbool(expr[pos])==1)
			{
				pos++;
				rtn=true;
				i++;
			}
	//	if(Isbool(expr[pos])==0)
			while(Isbool(expr[pos])==0)
			{
				pos++;
				rtn=false;
				i++;
	   }}
		if(i>1) Error(LIANXU);

	}
	else                                      //如果不是t 和f则产生相应的错误
	{
		if(expr[pos]==')')                    //如果发现一个")"
			Error(EMPTY_BRACKET);    //则是括号是空的,即括号内无布尔表达式。
		else if(expr[pos]=='\0')           //如果此时输入字符串结束
			Error(UNEXPECTED_END);  //则布尔表达式非法结束
		else
			Error(INVALID_CHAR_IN);    //否则输入字符串中含有非法字符
	}
	return rtn;
}
 
int Isbool(char ch)//布尔常量的判别。
{
	if(ch=='t'||ch=='T')
		return 1;
	if(ch=='f'||ch=='F')
		return 0;
	else
		return -1;
}


//出错处理函数,输入错误代码,可以指出错误位置,出错信息。
void Error(int ErrCode)
{
	
		cout<<endl;//换行
		while(pos--)
		cout<<' ';
		cout<<"^ 语法错误 !!!  "<<ErrCodeStr[ErrCode].c_str()<<endl;
		longjmp(errjb,1); //跳转到main函数中的setjmp调用处,并设置setjmp(errjb)返回值为1
		//longjmp(errjb,r);表示跳转到setjmp的调用处,并设置setjmp(errjb)返回值为r
	
}

⌨️ 快捷键说明

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