LL(1)文法代码(有一定的纠错能力)

本文介绍了一个简单的LR解析器实现过程,使用C++语言,并详细展示了如何通过栈操作来进行语法分析。通过对给定文法的分析,实现了对特定输入字符串的有效识别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <string.h>
#include <stack>
using namespace std;
/*
产生式为:
E -> TE`
E` -> + TE`
T -> FT`
T` -> *FT`
T` -> ε
F -> (E)
F -> a
*/
stack<int> s;
/*给终结符编号*/
int GetNumofTerminal(char ter){
	if (ter == 'a'){ return 5; }
	if (ter == '+'){ return 6; }
	if (ter == '*'){ return 7; }
	if (ter == '('){ return 8; }
	if (ter == ')'){ return 9; }
	if (ter == '$'){ return 10; }
}
/*通过序号找到终结符*/
char GetTerminalofNum(int num){
	if (num == 5){ return 'a'; }
	if (num == 6){ return '+'; }
	if (num == 7){ return '*'; }
	if (num == 8){ return '('; }
	if (num == 9){ return ')'; }
	if (num == 10){ return '$'; }
}
/*给非终结符编号(这个可以不写,用不到)*/
int GetNumofNon_Terminal(char* non){
	if (non == "E"){ return 0; }
	if (non == "E`"){ return 1; }
	if (non == "T"){ return 2; }
	if (non == "T`"){ return 3; }
	if (non == "F"){ return 4; }
}
/*通过序号找到非终结符*/
char *GetNon_TerminalofNum(int num){
	if (num == 0){ return "E"; }
	if (num == 1){ return "E`"; }
	if (num == 2){ return "T"; }
	if (num == 3){ return "T`"; }
	if (num == 4){ return "F"; }
}
/*手动创建分析表(同步记号符也写在里面)*/
bool Match_Table(int i, int j){
	if (i == 0 && j == 5){ s.pop(); s.push(1); s.push(2); cout << "E -> TE`"; return true; }
	else if (i == 0 && j == 8){ s.pop(); s.push(1); s.push(2); cout << "E -> TE`"; return true; }
	else if (i == 0 && j == 9){ s.pop(); cout << "出错,弹栈"; return true; }
	else if (i == 0 && j == 10){ s.pop(); cout << "出错,弹栈"; return true; }
	else if (i == 1 && j == 6){ s.pop(); s.push(1); s.push(2); s.push(6); cout << "E` -> + TE`"; return true; }
	else if (i == 1 && j == 9){ s.pop(); cout << "E` -> ε"; return true; }
	else if (i == 1 && j == 10){ s.pop(); cout << "E` -> ε"; return true; }
	else if (i == 2 && j == 5){ s.pop(); s.push(3); s.push(4); cout << "T -> FT`"; return true; }
	else if (i == 2 && j == 6){ s.pop(); cout << "出错,弹栈"; return true; }
	else if (i == 2 && j == 9){ s.pop(); cout << "出错,弹栈"; return true; }
	else if (i == 2 && j == 10){ s.pop(); cout << "出错,弹栈"; return true; }
	else if (i == 2 && j == 8){ s.pop(); s.push(3); s.push(4); cout << "T -> FT`"; return true; }
	else if (i == 3 && j == 6){ s.pop(); cout << "T` -> ε"; return true; }
	else if (i == 3 && j == 7){ s.pop(); s.push(3); s.push(4); s.push(7); cout << "T` -> *FT`"; return true; }
	else if (i == 3 && j == 9){ s.pop(); cout << "T` -> ε"; return true; }
	else if (i == 3 && j == 10){ s.pop(); cout << "T` -> ε"; return true; }
	else if (i == 4 && j == 5){ s.pop(); s.push(5); cout << "F -> a"; return true; }
	else if (i == 4 && j == 6){ s.pop(); cout << "出错,弹栈"; return true; }
	else if (i == 4 && j == 7){ s.pop(); cout << "出错,弹栈"; return true; }
	else if (i == 4 && j == 8){ s.pop(); s.push(9); s.push(0); s.push(8); cout << "F -> (E)"; return true; }
	else if (i == 4 && j == 9){ s.pop(); cout << "出错,弹栈"; return true; }
	else if (i == 4 && j == 10){ s.pop(); cout << "出错,弹栈"; return true; }
	else if (i == 10 && j == 10){ cout << "匹配成功!"; return true; }
	else { cout << "出错!" << endl; return false; }
}
int main(){
	/*显示分析表*/
	char ** table[5];
	for (int i = 0; i < 5; i++){
		table[i] = new char*[6];
	}
	for (int i = 0; i < 5; i++){
		for (int j = 0; j < 6; j++){
			table[i][j] = NULL;
		}
	}
	table[0][0] = "E -> TE`";
	table[0][3] = "E -> TE`";
	table[1][1] = "E` -> +TE`";
	table[1][4] = "E` -> ε";
	table[1][5] = "E` -> ε";
	table[2][0] = "T -> FT`";
	table[2][3] = "T -> FT`";
	table[3][1] = "T` -> ε";
	table[3][2] = "T` -> *FT`";
	table[3][4] = "T` -> ε";
	table[3][5] = "T` -> ε";
	table[4][0] = "F -> a";
	table[4][3] = "F -> (E)";
	cout << "分析表为:" << endl;
	for (int i = 0; i < 5; i++){
		for (int j = 0; j < 6; j++){
			if (table[i][j] == NULL){
				cout << "                ";
			}
			else{
				cout << table[i][j] << "     ";
			}
		}
		cout << endl;
	}
	for (int i = 0; i < 5; i++){
		delete[] table[i];
	}
	s.push(10);//$压栈
	s.push(0);//E压栈
	char* c = "a***aaa+a$";
	int size = strlen(c);
	int top = s.top();
	for (int i = 0; i < size;)
	{
		int flag = 0;
		int strhead = GetNumofTerminal(c[i]);
		while (s.top() != strhead){
			int strhead = GetNumofTerminal(c[i]);
			cout << "----------------------------" << endl;
			/*输出栈顶元素,既可能是终结符也可能是非终结符*/
			if (s.top() >= 0 && s.top() <= 4){
				cout << "栈顶:" << GetNon_TerminalofNum(s.top()) << "  输入的符号为:" << c[i] << endl;
			}
			if (s.top()>4 && s.top() <= 10){
				cout << "栈顶:" << GetTerminalofNum(s.top()) << "  输入的符号为:" << c[i] << endl;
			}
			/*检验是否匹配,不匹配做出错误处理*/
			if (Match_Table(s.top(), strhead)){
				cout << endl;
				flag = 1;
			}
			else if (strhead == 10){
				cout << s.top() << endl;
				if (s.top() >= 0 && s.top() <= 4){
					cout << "栈顶元素" << GetNon_TerminalofNum(s.top()) << "出错!弹栈" << endl;
				}
				if (s.top()>4 && s.top() <= 10){
					cout << "栈顶元素" << GetTerminalofNum(s.top()) << "出错!弹栈" << endl;
				}
				s.pop();
			}
			else{
				cout << "放弃这个输入符" << c[i] << endl;
				i++;
				break;
			}
		}
		/*若匹配成功则准备输入下一字符*/
		if (flag == 1){
			cout << "匹配" << GetTerminalofNum(s.top()) << endl;
			s.pop();
			i++;
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值