编译原理实验-预测分析程序

要求

(1)总体要求:
1)根据文法手工或程序方式构造预测分析表;
2)采用程序方式构造预测分析表时,需计算First()和Follow()集合,有一定难度;
3)根据预测分析表,设计并实现预测分析总控程序,完成自上而下的语法分析器。
(2)文法的定义(可以选择此文法,也可以自己选择其他文法)
编译原理实验-预测分析程序_第1张图片
(3)给出当输入串为:(i1+i2)*(i3+i4)的分析过程。(输出分析过程中的栈,输入串和利用的产生式等信息)

代码

int a;//当前正在读的字符的下标
char VT[7] = {'+','*','(',')','i','#'};//终结符号
int length_vt = 6;//终结符号的个数
char VN[6] = {'E','M','T','N','F' };//非终结符号用M代替了E' 用N代替了T’
int length_vn = 5;//非终结符号的个数
string equation[8] = { "TM","+TM","","FN","*FN","","(E)","i" };//产生式表
stack<char> sta;//分析栈
bool flag = false;//判断分析是否结束
string str;//存放用户输入的字符串
string used;//所使用的产生式
string table[5][6] = { 
{"error","error","TM","error","TM","error" },
{"+TM","error","error","","error",""},
{"error","error","FN","error","FN","error"} ,
{"","*FN","error","","error",""} ,
{"error","error","(E)","error","i","error"} };//预测分析表
  1. 功能说明:判断栈顶符号是否是非终结符
  2. 输出:是非终结符返回true,是终结符返回false
bool is_vn()//判断是否为非终结符
{
	if ((sta.top() >= 'A')&& (sta.top() <= 'Z'))
		return true;
	else 
		return false;
}
  1. 功能说明:初始化操作,将’#'和起始符号先入栈,同时在输入串最后加一个‘#’结束符。
void init()//做初始化
{
	sta.push('#');
	sta.push('E');//将'#'和起始符号先入栈
	str = str + '#';//将输入串最后加一个‘#’结束符。
	a = 0;
}
  1. 功能说明:进行一次栈顶符号分析,若栈顶符号是终结符则直接和输入串当前符号进行比较,若是非终结符,则查预测分析表得到相应的产生式,将其压栈。
  2. 输出:错误提示信息。
void analyse()//对一个字符的分析情况
{
	string s;//所使用的的产生式
	if(is_vn()==false)//判断是否为非终结符
	{
		if (str[a] == '#'&&(sta.top()=='#'))
		{
			cout << "分析成功..." << endl;
			flag = true;
			return;
		}
		else if (sta.top() == str[a])//如果栈顶元素和当前字符一致,则读入下一个字符,且栈顶元素出栈
		{	 
			s = s +str[a]+ "匹配";
			used = s;
	//		cout << "当前栈顶元素" << sta.top() << "当前字符" << str[a] << endl;
			a++;
			sta.pop();
			return;
		}
		else
		{
			flag = true;//已经判断出了该句子不属于此文法,所以分析结束
			cout << "该句子不属于该文法" << endl;
			return;
		}
	}
	else {
		for (int i = 0; i < length_vn; i++)//查表判断
		{
			if (sta.top() == VN[i])
			{
				for (int j = 0; j < length_vt; j++)
				{
					if (VT[j] == str[a])
					{
						if (table[i][j] == "error")
						{
							cout << "预测分析表没有对应的产生式" << endl;
							flag = true;//已经判断出了该句子不属于此文法,所以分析结束
							return;
						}
						else if (table[i][j] == "")
						{
				//			cout << "出栈:" << sta.top() << endl;
							s = s + VN[i];
							s = s + "->空";
							used = s;//将使用的产生式放入used
							sta.pop();
							return;
						}
						else//将当前栈顶出栈,将预测分析表对应的产生式右部进栈
						{
							sta.pop();
							for (int  z= table[i][j].length()-1; z >=0 ; z--)
							{
								sta.push(table[i][j][z]);
							}	
							s=s+ VN[i]+"->"+ table[i][j];
							used = s;
							return;
						}
					}
				}
				cout << "error:这个输入串中的字符不属于该文法" << endl;
				flag = true;
				return;
			}
		}
		cout << "error:该栈顶的符号不属于该文法" << endl;
		flag = true;
		return;
	}
}
  1. 功能说明:将栈中的符号反向输出(栈顶符号最后输出)
  2. 输出:当前栈的内容
string printstack()//顺序输出栈中的符号
{
	string s;//存放栈中的符号
	string sf;//栈中的元素的反序
	int  num = sta.size();
	for (int i = 0; i < num; i++)//把sta栈的内容给s
	{
		sf=sf+sta.top();
		sta.pop();
	}
	for (int i = num-1; i >=0; i--)//反序
	{
		s = s + sf[i];
	}
	for (int i = 0; i < num; i++)//恢复sta
	{
		sta.push(s[i]);
	}
	return s;
}
  1. 功能说明:返回输入串
string getstr()//返回输入串
{
	string s;
	for (int i = a; i < str.length(); i++)
	{
		s=s+str[i];
	}
	return s;
}
  1. 功能说明:循环调用analyse函数,直到分析成功,或者直到过程中分析得到该句子不是此文法的句子。
int main()
{
	cout << "请输入一个字符串:" << endl;
	cin>>str;
	init();
	int step = 0;
	cout << setw(25) << setiosflags(ios::left) << "步骤" << setw(25) <<"符号栈" << setw(25) << "输入串"<< setw(25) << "所用产生式" << endl;
    while(flag==false)
	{	
		cout << setw(25) << setiosflags(ios::left) << step << setw(25)<<printstack()<< setw(25)<<getstr()<<setw(25)<< used<<endl;
		analyse();
		step++;		
	}
	return 0;
}

运行结果

编译原理实验-预测分析程序_第2张图片

你可能感兴趣的:(笔记,c++,编译器)