可直接运行!编译原理LL1文法c语言

用c语言编写的

这里一共是三个文件.h和.cpp和main.cpp文件

有什么不懂的可以与我留言进行交流

本人用的IDE是  vs studio

Grammar.h

#pragma once
#include <string>
#include <set>
#include <map>
#include <vector>

using std::map;
using std::set;
using std::string;
using std::vector;

// 产生式结构体
struct pstring
{
	char left;
	string right;
};

class Grammar
{
public:
	Grammar();
	// 拷贝构造函数
	Grammar(const Grammar&);
	// 用户输入初始化文法
	void init();
	// 初始化产生式集合
	void init_P();
	// 将产生式右侧第一个字符为非终结符的进行代入替换
	void first_letter_substitution();
	// 将不可达的产生式删除
	void del_unreachable_production();
	// 提取左公因式
	void parsing_common_factor();
	// 消除直接左递归
	void parsing_direct_left_recursion();
	// 消除间接左递归
	void parsing_indirect_left_recursion();
	// 计算First集合
	void cal_First();
	// 计算Follow集合
	void cal_Follow();
	// 调用递归方法计算Follow集合
	void cal_Follow_recur();
	// 计算Select集合
	void cal_Select();
	// 生成预测分析表,当同一单元格有多个式子时,返回false
	bool get_Table();
	// 判断是否为LL(1)文法
	bool is_LL1();
	// 预测分析法进行语法分析
	bool grammar_parsing();
	// 对某个非终结符求First集合
	void get_First_recur(char);
	// 不递归的求出Follow集合
	void get_Follow();
	// 对某个非终结符求Follow集合
	void get_Follow_recur(char, int);
	// 判断是否为终结符
	bool inVt(char);
	// 判断是否为非终结符
	bool inVn(char);
	// 判断产生式是否存在左公因式
	bool have_common_factor();
	// 判断产生式是否存在左递归式
	bool have_left_recursion();
	// 求终结符在预测分析表中的列标
	int index_in_terminal(char);
	// 求非终结符在预测分析表中的行标
	int index_in_nonterminal(char);
	// 输出产生式集
	void printProduction();
	// 输出First集
	void printFirst();
	// 输出Follow集
	void printFollow();
	// 输出Select集
	void printSelect();
	// 输出预测分析表
	void printTable();
	~Grammar();

private:
	// 终结符集,小写字母
	set<char> Vt;
	// 非终结符集,大写字母
	set<char> Vn;
	// 产生式集合P
	vector<pstring> P;
	// 产生式中包含的终结符集
	set<char> terminal;
	// 产生式中包含的非终结符集
	set<char> nonterminal;
	// First集合
	map<char, set<char>> first_set;
	// Follow集合
	map<char, set<char>> follow_set;
	// Select集合
	vector<set<char>> select_set;
	// 预测分析表
	int** predict_table;
	// 产生式数量
	int pnum;
	// 开始符号
	char S;
	// LL(1)文法标志
	bool LL1;
};

 Grammar.c文件

#include "Grammar.h"
#include <iostream>
#include <stack>

using std::cin;
using std::cout;
using std::stack;

Grammar::Grammar()
{
	int i, j;

#pragma region 初始化终结集与非终结集
	for (i = 97, j = 65; (i <= 122) && (j <= 90); i++, j++)
	{
		this->Vt.insert(char(i));
		this->Vn.insert(char(j));
	}
	// 特别的,终结符中用$表示空串,#表示结束符
	Vt.insert('$');
	Vt.insert('#');
#pragma endregion

	this->P.clear();
	this->terminal.clear();
	this->nonterminal.clear();
	this->first_set.clear();
	this->follow_set.clear();
	this->select_set.clear();
	this->predict_table = new int* [1];
	this->pnum = 0;
	this->S = 'S';
	this->LL1 = false;
}

// 拷贝构造函数
Grammar::Grammar(const Grammar& g)
{
	this->Vn = g.Vn;
	this->Vt = g.Vt;
	this->P = g.P;
	this->terminal = g.terminal;
	this->nonterminal = g.nonterminal;
	this->first_set = g.first_set;
	this->follow_set = g.follow_set;
	this->select_set = g.select_set;
	this->predict_table = new int* [1];
	this->pnum = g.pnum;
	this->S = g.S;
	this->LL1 = g.LL1;
}

// 用户输入初始化文法
void Grammar::init()
{
#pragma region 初始化开始符号和产生式集合
	// 用户输入开始符号
	char start;
	while (true)
	{
		cout << "请输入开始符号:";
		cin >> start;
		if (inVn(start))
		{
			this->S = start;
			break;
		}
		else
		{
			cout << "开始符号应在非终结集中!请重新输入\n";
		}
	}
	cout << '\n';
#pragma endregion

	// 用户输入产生式集合
	init_P();
}

// 初始化产生式集合
void Grammar::init_P()
{
	int i, flag;
	this->pnum = 0;
	cout << "请输入产生式:(输入0结束)\n"
		"形如:S-aA,空串以$表示\n\n";

	while (true)
	{
		flag = 0;
		string p;
		cin >> p;
		if (p == "0")
		{
			break;
		}
		else
		{
			char left = p[0];
			this->nonterminal.insert(left);
			if (!inVn(left))
			{
				cout << "产生式左端应为非终结符!请重新输入\n\n";
			}
			else
			{
				string right;
				int i = p.find("-");
				if (i == string::npos)
				{
					cout << "产生式格式有误!\n";
					flag = 1;
				}
				else
				{
					right = p.substr(i + 1, p.length());

					for (i = 0; i < right.length(); i++)
					{
						if (!inVt(right[i]) && !inVn(right[i]))
						{
							cout << "产生式左部含非法字符!\n";
							flag = 1;
							break;
						}
						if (inVt(right[i]))
						{
							this->terminal.insert(right[i]);
						}
						if (inVn(right[i]))
						{
							this->nonterminal.insert(right[i]);
						}
					}

					for (i = 0; i < this->P.size(); i++)
					{
						if (this->P[i].left == left && this->P[i].right == right)
						{
							// 重复标志
							flag = 1;
							break;
						}
					}
				}

				if (flag != 1)
				{
					pstring temp;
					temp.left = left;
					temp.right = right;
					this->P.push_back(temp);
					this->pnum++;
					cout << "产生式添加成功\n\n";
				}
				else
				{
					cout << "请输入新的产生式:\n\n";
				}
			}
		}
	}
	this->terminal.insert('#');
}

// 检查产生式p是否在产生式集合中
bool find_production(const vector<pstring>& Pset, const pstring& p)
{
	int i;
	for (i = 0; i < Pset.size(); i++)
	{
		if (Pset[i].left == p.left && Pset[i].right == p.right)
			return true;
	}
	return false;
}

/*
for(i=1;i<=n;i++)
   for(j=1;j<=i-1;j++)
   { 把形如Ai→Ajγ的产生式改写成Ai→δ1γ /δ2γ /…/δkγ
	   其中Aj→δ1 /δ2 /…/δk是关于的Aj全部规则;
	   消除Ai规则中的直接左递归;
   }
*/

// 将产生式右侧第一个字符为非终结符的进行代入替换
void Grammar::first_letter_substitution()
{
	int i, j, m, n;
	set<char>::iterator it1, it2;
	for (it1 = this->nonterminal.begin(), i = 0; it1 != this->nonterminal.end(); it1++, i++)
	{
		for (it2 = this->nonterminal.begin(), j = 0; j < i; it2++, j++)
		{
			vector<pstring> newP;
			for (m = 0; m < this->pnum; m++)
			{
				if (this->P[m].left == *it1 && this->P[m].right[0] == *it2)
				{
					for (n = 0; n < this->pnum; n++)
					{
						if (this->P[n].left == *it2)
						{
							pstring newp;
							newp.left = *it1;
							if (this->P[n].right != "$")
								newp.right = this->P[n].right + this->P[m].right.substr(1);
							else
								newp.right = this->P[m].right.substr(1);
							newP.push_back(newp);
						}
					}
				}
			}

			set<int> erase_index;
			for (m = 0; m < this->pnum; m++)
			{
				if (this->P[m].left == *it1)
				{
					erase_index.insert(m);
					if (this->P[m].right[0] != *it2)
					{
						newP.push_back(this->P[m]);
					}
				}
			}

			for (auto erase_it = erase_index.rbegin(); erase_it != erase_index.rend(); erase_it++)
			{
				this->P.erase(this->P.begin() + *erase_it);
			}

			for (auto p_it = newP.begin(); p_it != newP.end(); p_it++)
			{
				this->P.push_back(*p_it);
			}
			this->pnum = this->P.size();
		}
	}
}

// 将不可达的产生式删除
void Grammar::del_unreachable_production()
{
	int i, j;
	// 记录能够推导到的非终结符集
	set<char> reachable;
	stack<char> s;
	s.push(this->S);
	while (!s.empty())
	{
		char ch = s.top();
		s.pop();
		reachable.insert(ch);
		for (i = 0; i < this->pnum; i++)
		{
			if (this->P[i].left == ch)
			{
				for (j = 0; j < this->P[i].right.length(); j++)
				{
					if (inVn(this->P[i].right[j]))
					{
						if (reachable.find(this->P[i].right[j]) == reachable.end())
						{
							reachable.insert(this->P[i].right[j]);
							s.push(this->P[i].right[j]);
						}
					}
				}
			}
		}
	}

	this->nonterminal = reachable;
	// 遍历产生式集,如果左端不在reachable中,则准备将其删除
	set<int> del_index;
	for (i = 0; i < this->pnum; i++)
	{
		if (reachable.find(this->P[i].left) == reachable.end())
			del_index.insert(i);
	}
	// 下标由大到小的删除不可达产生式
	for (auto del_iter = del_index.rbegin(); del_iter != del_index.rend(); del_iter++)
	{
		this->P.erase(this->P.begin() + *del_iter);
	}
	this->pnum = this->P.size();
}

// 提取左公因式
void Grammar::parsing_common_factor()
{
	int i, j;
	char new_nt = 90; // 新增非终结符,从Z开始向A加入
	int flag = 1;	  // 如果有左公因式,那就要对产生式集合做出改变,flag置1
	while (flag != 0)
	{
		flag = 0;
		set<int> lcf; // 用一个set记录拥有左公因子的产生式下标,倒序删除就不会打乱
		for (i = 0; i < this->pnum; i++)
		{
			lcf.clear();
			char left = this->P[i].left;
			string right;
			int length;
			for (length = this->P[i].right.length(); length >= 1; length--)
			{
				lcf.clear();
				lcf.insert(i);
				right = this->P[i].right.substr(0, length);
				for (j = 0; j < this->pnum; j++)
				{
					if (j != i)
					{
						if (this->P[j].left == left)
						{
							if (this->P[j].right.length() >= length)
							{
								if (this->P[j].right.substr(0, length) == right)
								{
									lcf.insert(j);
								}
							}
						}
					}
				}
				if (lcf.size() > 1)
				{
					flag = 1;
					while (this->nonterminal.find(new_nt) != this->nonterminal.end())
						new_nt--;
					this->nonterminal.insert(new_nt);

					for (auto lcf_iter = lcf.rbegin(); lcf_iter != lcf.rend(); lcf_iter++)
					{
						string new_right;
						if (this->P[*lcf_iter].right.length() == length)
						{
							new_right = '$'; // S->ab,提取ab后,Z->ε
						}
						else
						{
							new_right = this->P[*lcf_iter].right.substr(length, this->P[*lcf_iter].right.length()); // S->abB,提取ab后,Z->B
						}
						pstring new_p;
						new_p.left = new_nt;
						new_p.right = new_right;
						this->P.erase(this->P.begin() + *lcf_iter);
						this->P.push_back(new_p);
					}

					pstring new_p2;
					new_p2.left = left;
					new_p2.right += right;
					new_p2.right += new_nt--;
					this->P.push_back(new_p2);
				}

				if (flag == 1)
				{
					this->pnum = this->P.size();
					break;
				}
			}

			if (flag == 1)
			{
				break;
			}
		}
	}
}

// 消除左递归
void Grammar::parsing_direct_left_recursion()
{
	int i, j;
	char new_nt = 90; // 新增非终结符,从Z开始向A加入
	int flag = 1;
	while (flag)
	{
		flag = 0;
		for (auto nt_it = this->nonterminal.begin(); nt_it != this->nonterminal.end(); nt_it++)
		{
			set<int> recur_index; // 左递归产生式集合,如S->Sa, S->Sb
			set<int> end_index;	  // 非递归式集合,作为终结
			for (i = 0; i < this->pnum; i++)
			{
				if (this->P[i].left == *nt_it)
				{
					if (this->P[i].left == this->P[i].right[0])
					{
						recur_index.insert(i);
					}
					else
					{
						end_index.insert(i);
					}
				}
			}

			if (recur_index.size() != 0)
			{
				flag = 1;
				while (this->nonterminal.find(new_nt) != this->nonterminal.end())
					new_nt--;
				this->nonterminal.insert(new_nt);

				// 对递归部分,构造S'->aS'
				for (auto recur_iter = recur_index.begin(); recur_iter != recur_index.end(); recur_iter++)
				{
					pstring newp;
					newp.left = new_nt;
					newp.right = this->P[*recur_iter].right.substr(1, P[*recur_iter].right.length());
					newp.right += new_nt;
					this->P.push_back(newp);
				}

				// 对非递归部分,构造S->aS'
				for (auto end_iter = end_index.begin(); end_iter != end_index.end(); end_iter++)
				{
					pstring newp;
					newp.left = *nt_it;
					if (this->P[*end_iter].right != "$")
						newp.right = this->P[*end_iter].right;
					newp.right += new_nt;
					this->P.push_back(newp);
				}

				pstring epsilon;
				epsilon.left = new_nt;
				epsilon.right = "$";
				this->P.push_back(epsilon);

				set<int> erase_index(recur_index.begin(), recur_index.end());
				erase_index.insert(end_index.begin(), end_index.end());

				for (auto erase_it = erase_index.rbegin(); erase_it != erase_index.rend(); erase_it++)
				{
					this->P.erase(this->P.begin() + *erase_it);
				}
			}

			if (flag == 1)
			{
				this->pnum = this->P.size();
				break;
			}
		}
	}
}

// 计算First集合
void Grammar::cal_First()
{
	// 首先给每个非终结符初始化一个空的First集合
	for (auto nterm_iter = this->nonterminal.begin(); nterm_iter != this->nonterminal.end(); nterm_iter++)
	{
		set<char> value;
		this->first_set.insert(std::make_pair(*nterm_iter, value));
	}
	// 对每个非终结符求First集合
	for (auto nterm_iter = this->nonterminal.begin(); nterm_iter != this->nonterminal.end(); nterm_iter++)
	{
		get_First_recur(*nterm_iter);
	}
}

// 调用递归方法计算Follow集合
void Grammar::cal_Follow_recur()
{
	// 首先给每个非终结符初始化Follow集合,特别的对S添加#结束符
	for (auto nterm_iter = this->nonterminal.begin(); nterm_iter != this->nonterminal.end(); nterm_iter++)
	{
		set<char> value;
		if (*nterm_iter == this->S)
		{
			value.insert('#');
		}
		this->follow_set.insert(std::make_pair(*nterm_iter, value));
	}

	// 对每个非终结符求Follow集合
	for (auto nterm_iter = this->nonterminal.begin(); nterm_iter != this->nonterminal.end(); nterm_iter++)
	{
		get_Follow_recur(*nterm_iter, 1);
	}
}

// 不使用递归计算Follow集合
void Grammar::cal_Follow()
{
	// 首先给每个非终结符初始化Follow集合,特别的对S添加#结束符
	for (auto nterm_iter = this->nonterminal.begin(); nterm_iter != this->nonterminal.end(); nterm_iter++)
	{
		set<char> value;
		if (*nterm_iter == this->S)
		{
			value.insert('#');
		}
		this->follow_set.insert(std::make_pair(*nterm_iter, value));
	}

	get_Follow();
}

// 计算Select集合
void Grammar::cal_Select()
{
	int i, j;
	for (i = 0; i < this->pnum; i++)
	{
		int countEmpty = 0; // 右端全部能推出$,则使用 Select(A-a) = First(a)-$ ∪ Follow(A)
		set<char> select;
		for (j = 0; j < this->P[i].right.length(); j++)
		{
			char rj = this->P[i].right[j];
			// 遇到终结符
			if (inVt(rj))
			{
				if (rj != '$') // 不是空串,则直接加入并结束
					select.insert(this->P[i].right[j]);
				else if (rj == '$')
					countEmpty++;
				break;
			}
			// 遇到非终结符
			else
			{
				// 将其First集合中非$符加入
				for (auto value_iter = this->first_set[rj].begin(); value_iter != this->first_set[rj].end(); value_iter++)
				{
					if (*value_iter != '$')
						select.insert(*value_iter);
				}
				if (this->first_set[rj].find('$') != this->first_set[rj].end())
				{
					countEmpty++;
				}
				else
				{
					break;
				}
			}
		}

		// 将Follow集合并入
		if (countEmpty == this->P[i].right.length())
		{
			for (auto value_iter = this->follow_set[this->P[i].left].begin(); value_iter != this->follow_set[this->P[i].left].end(); value_iter++)
			{
				select.insert(*value_iter);
			}
		}

		this->select_set.push_back(select);
	}
}

// 生成预测分析表,当同一单元格有多个式子时,返回false
bool Grammar::get_Table()
{
	int i, j;

#pragma region 初始化预测分析表
	this->predict_table = new int* [this->nonterminal.size()];
	for (i = 0; i < this->nonterminal.size(); i++)
	{
		this->predict_table[i] = new int[this->terminal.size()];
	}
	for (i = 0; i < this->nonterminal.size(); i++)
	{
		for (j = 0; j < this->terminal.size(); j++)
		{
			this->predict_table[i][j] = -1;
		}
	}
#pragma endregion

	for (i = 0; i < this->pnum; i++)
	{
		int row = index_in_nonterminal(this->P[i].left);

		for (auto s_iter = this->select_set[i].begin(); s_iter != this->select_set[i].end(); s_iter++)
		{
			int column = index_in_terminal(*s_iter);
			if (this->predict_table[row][column] != -1)
			{
				return false;
			}
			else
			{
				this->predict_table[row][column] = i;
			}
		}
	}
	return true;
}

// 判断是否为LL(1)文法
bool Grammar::is_LL1()
{
	if (!get_Table())
	{
		this->LL1 = false;
		return false;
	}
	this->LL1 = true;
	return true;
}

bool Grammar::grammar_parsing()
{
	int i, j = 0;
	if (this->LL1)
	{
		string sentence;
		cout << "请输入一个句子:";
		cin >> sentence;
		for (i = 0; i < sentence.length(); i++)
		{
			if (inVn(sentence[i]))
			{
				cout << "syntax error! 句中不应出现非终结符\n";
				return false;
			}
			if (!(inVn(sentence[i]) || inVt(sentence[i])))
			{
				cout << "syntax error! 句中含非法字符\n";
				return false;
			}
		}
		if (sentence[i - 1] != '#')
			sentence += '#';

		// 构造运算栈,将#和开始符号入栈
		stack<char> s;
		s.push('#');
		s.push(this->S);

		// 定义读头
		char readhead = sentence[j++];
		while (s.size() != 1)
		{
			char top = s.top();
			s.pop();

			if (inVt(top))
			{
				if (top != '$')
				{
					if (top == readhead)
						readhead = sentence[j++];
					else
					{
						cout << "syntax error! 无法匹配\n";
						return false;
					}
				}
			}
			else
			{
				int row = index_in_nonterminal(top);
				int column = index_in_terminal(readhead);
				int index = this->predict_table[row][column];
				if (index == -1)
				{
					cout << "syntax error! 无法匹配\n";
					return false;
				}
				else
				{
					int k;
					for (k = this->P[index].right.length() - 1; k >= 0; k--)
					{
						s.push(this->P[index].right[k]);
					}
				}
			}
		}

		if (s.top() == readhead)
			return true;
	}
	cout << "syntax error! 无法匹配\n";
	return false;
}

// 求target的First集合
void Grammar::get_First_recur(char target)
{
	int i, j;
	int isEmpty = 0;	// 产生空串标识符,0表示不能产生$
	int countEmpty = 0; // 只有当X->Y1Y2...Yn中,Y1-Yn都可以产生空串时,First(X)才有#
	for (i = 0; i < this->pnum; i++)
	{
		// 与产生式左端匹配
		if (this->P[i].left == target)
		{
			// 终结符直接加入First
			if (inVt(this->P[i].right[0]))
			{
				this->first_set[target].insert(this->P[i].right[0]);
			}
			else
			{
				// X->Y1Y2...Yj...Yk这样的表达式
				for (j = 0; j < this->P[i].right.length(); j++)
				{
					char Yj = this->P[i].right[j];
					// 如果Yj是终结符,则停止递归
					if (inVt(Yj))
					{
						this->first_set[target].insert(Yj);
						break;
					}
					// Yj是非终结符则应递归,先求出Yj的First集
					get_First_recur(Yj);

					// 将Yj的结果复制给X
					for (auto value_iter = this->first_set[Yj].begin(); value_iter != this->first_set[Yj].end(); value_iter++)
					{
						if (*value_iter == '$')
						{
							isEmpty = 1;
						}
						else
						{
							this->first_set[target].insert(*value_iter);
						}
					}

					if (isEmpty == 0) // Yj不能产生空,迭代结束
					{
						break;
					}
					else // 如果能产生空串,那么需要确认右侧全都能产生空串
					{
						countEmpty += 1;
						isEmpty = 0;
					}
				}
				if (countEmpty == this->P[i].right.length())
				{
					this->first_set[target].insert('$');
				}
			}
		}
	}
}

// 递归的求target的Follow集合
void Grammar::get_Follow_recur(char target, int recur_count)
{
	int i, j;
	for (i = 0; i < this->pnum; i++)
	{
		// 限制最大递归次数,防止右递归产生式求Follow时死循环
		if (recur_count > this->pnum)
		{
			break;
		}
		int index = this->P[i].right.find(target); // 找到target在产生式中P[i]右端的下标

		// !npos表示找到target,下面对形如S->aAB这样的产生式(A不为最右)
		if (index != string::npos && index < this->P[i].right.length() - 1)
		{
			char next = this->P[i].right[index + 1];
			// 如果是终结符直接加入
			if (inVt(next))
			{
				this->follow_set[target].insert(next);
			}
			else
			{
				int hasEmpty = 0; // 含有终结符标识
				for (auto next_iter = this->first_set[next].begin(); next_iter != this->first_set[next].end(); next_iter++)
				{
					if (*next_iter == '$')
						hasEmpty = 1;
					else
					{
						this->follow_set[target].insert(*next_iter);
					}
				}

				// 若为 S->aABC,当First(B)含有$时,首先做Follow(A)+= First(B)-$,即上面做的部分;然后做Follow(A)+=Follow(B)
				if (hasEmpty == 1 && ((index + 1) < this->P[i].right.length() - 1))
				{
					get_Follow_recur(next, ++recur_count);
					for (auto next_iter = this->follow_set[next].begin(); next_iter != this->follow_set[next].end(); next_iter++)
					{
						this->follow_set[target].insert(*next_iter);
					}
				}

				// 仅对 S->aAB,当First(B)含有$时,Follow(A)+=Follow(S)。即target后面的非终结符为最右端
				// 特别的,对于 S->aSA,First(A)含有$,需要避免无限递归
				if (hasEmpty == 1 && ((index + 1) == this->P[i].right.length() - 1) && this->P[i].left != target)
				{
					get_Follow_recur(this->P[i].left, ++recur_count);
					for (auto left_iter = this->follow_set[this->P[i].left].begin(); left_iter != this->follow_set[this->P[i].left].end(); left_iter++)
					{
						this->follow_set[target].insert(*left_iter);
					}
				}
			}
		}
		// 对于形如 S->aA,则Follow(A)+=Follow(S)
		else if (index != string::npos && index == this->P[i].right.length() - 1 && target != this->P[i].left)
		{
			get_Follow_recur(this->P[i].left, ++recur_count);
			for (auto left_iter = this->follow_set[this->P[i].left].begin(); left_iter != this->follow_set[this->P[i].left].end(); left_iter++)
			{
				this->follow_set[target].insert(*left_iter);
			}
		}
	}
}

// 非递归的求target的Follow集合
void Grammar::get_Follow()
{
	int i, j;
	int flag = 1; // 当所有Follow集合不再变化时,停止循环

	while (flag)
	{
		flag = 0; // 设flag为0,当有修改时设为1

		// 对每个产生式
		for (i = 0; i < this->pnum; i++)
		{
			char left = this->P[i].left;
			for (j = 0; j < this->P[i].right.length(); j++)
			{
				char rj = this->P[i].right[j];
				if (inVn(rj))
				{
					char brj;								 // behind rj
					int psize = this->follow_set[rj].size(); // previous size,Follow(rj)的原始值
					if (j < this->P[i].right.length() - 1)	 // Follow(rj)+=First(brj)
					{
						brj = this->P[i].right[j + 1];
						if (inVt(brj))
						{
							this->follow_set[rj].insert(brj);
						}
						else
						{
							int emptyFlag = 0;
							for (auto brj_iter = this->first_set[brj].begin(); brj_iter != this->first_set[brj].end(); brj_iter++)
							{
								if (*brj_iter != '$')
									this->follow_set[rj].insert(*brj_iter);
								else
									emptyFlag = 1;
							}

							if (emptyFlag == 1) // A->aBCD,C若能推出ε,Follow(B)+=Follow(C)
							{
								for (auto brj_iter = this->follow_set[brj].begin(); brj_iter != this->follow_set[brj].end(); brj_iter++)
								{
									this->follow_set[rj].insert(*brj_iter);
								}
							}
						}
					}
					else // Follow(rj)+=Follow(left)
					{
						for (auto left_iter = this->follow_set[left].begin(); left_iter != this->follow_set[left].end(); left_iter++)
						{
							this->follow_set[rj].insert(*left_iter);
						}
					}
					if (psize != this->follow_set[rj].size())
						flag = 1;
				}
			}
		}
	}
}

// 判断字符是否为非终结符
bool Grammar::inVn(char s)
{
	if (this->Vn.find(s) != this->Vn.end())
		return true;
	return false;
}

// 判断产生式是否存在左公因式
bool Grammar::have_common_factor()
{
	int i, j;
	Grammar temp(*this);
	temp.first_letter_substitution();

	for (auto nt_iter = temp.nonterminal.begin(); nt_iter != temp.nonterminal.end(); nt_iter++)
	{
		for (i = 0; i < temp.pnum; i++)
		{
			if (temp.P[i].left == *nt_iter)
			{
				for (j = 0; j < temp.pnum; j++)
				{
					if (i != j && temp.P[j].left == *nt_iter)
					{
						if (temp.P[i].right[0] == temp.P[j].right[0])
							return true;
					}
				}
			}
		}
	}
	return false;
}

// 判断产生式是否存在左递归式
bool Grammar::have_left_recursion()
{
	int i;
	Grammar temp(*this);
	temp.first_letter_substitution();

	for (i = 0; i < temp.pnum; i++)
	{
		if (temp.P[i].left == temp.P[i].right[0])
		{
			return true;
		}
	}

	return false;
}

// 判断字符是否为终结符
bool Grammar::inVt(char e)
{
	if (this->Vt.find(e) != this->Vt.end())
		return true;
	return false;
}

// 求终结符在预测分析表中的列标
int Grammar::index_in_terminal(char target)
{
	int i = 0;
	for (auto t_iter = this->terminal.begin(); t_iter != this->terminal.end(); t_iter++, i++)
	{
		if (*t_iter == target)
			return i;
	}
	return 0;
}

// 求非终结符在预测分析表中的行标
int Grammar::index_in_nonterminal(char target)
{
	int i = 0;
	for (auto nt_iter = this->nonterminal.begin(); nt_iter != this->nonterminal.end(); nt_iter++, i++)
	{
		if (*nt_iter == target)
			return i;
	}
	return 0;
}

// 输出产生式集
void Grammar::printProduction()
{
	int i;
	cout << "--------------产生式集合---------------\n\n";
	for (i = 0; i < this->pnum; i++)
	{
		cout << this->P[i].left << "->" << this->P[i].right << '\n';
	}
	cout << '\n';
}

// 输出First集合
void Grammar::printFirst()
{
	cout << "-----------First集合-------------\n\n";

	for (auto first_iter = this->first_set.begin(); first_iter != this->first_set.end(); first_iter++)
	{
		cout << "非终结符" << first_iter->first << ":";

		for (auto value_iter = first_iter->second.begin(); value_iter != first_iter->second.end(); value_iter++)
		{
			cout << *value_iter << " ";
		}
		cout << '\n';
	}
	cout << '\n';
}

// 输出Follow集合
void Grammar::printFollow()
{
	cout << "-----------Follow集合-------------\n\n";

	for (auto follow_iter = this->follow_set.begin(); follow_iter != this->follow_set.end(); follow_iter++)
	{
		cout << "非终结符" << follow_iter->first << ":";

		for (auto value_iter = follow_iter->second.begin(); value_iter != follow_iter->second.end(); value_iter++)
		{
			cout << *value_iter << " ";
		}
		cout << '\n';
	}
	cout << '\n';
}

// 输出Select集合
void Grammar::printSelect()
{
	cout << "------------Select集合------------\n\n";
	int i;
	for (i = 0; i < this->pnum; i++)
	{
		cout << this->P[i].left << "->" << this->P[i].right << ":\t";

		for (auto iter = this->select_set[i].begin(); iter != this->select_set[i].end(); iter++)
		{
			cout << *iter << " ";
		}
		cout << '\n';
	}
	cout << '\n';
}

// 输出预测分析表
void Grammar::printTable()
{
	cout << "-------------预测分析表---------------\n\n";

	for (auto it = this->terminal.begin(); it != this->terminal.end(); it++)
	{
		if (*it == '$')
			cout << "\t" << '#';
		else
			cout << "\t" << *it;
	}
	cout << '\n';

	int i = 0;
	for (auto it = this->nonterminal.begin(); it != this->nonterminal.end(); it++, i++)
	{
		cout << *it;
		for (int j = 0; j < this->terminal.size(); j++)
		{
			if (this->predict_table[i][j] != -1)
			{
				cout << "\t";
				cout << this->P[this->predict_table[i][j]].left << "->" << this->P[this->predict_table[i][j]].right;
			}
			else
			{
				cout << "\t";
			}
		}
		cout << '\n';
	}
	cout << '\n';
}

Grammar::~Grammar()
{
	this->Vn.clear();
	this->Vt.clear();
	this->P.clear();
	this->terminal.clear();
	this->nonterminal.clear();
	this->first_set.clear();
	this->follow_set.clear();
	this->select_set.clear();
	delete[] this->predict_table;
}

 main.cpp文件

#include "Grammar.h"
#include <iostream>

using std::cout;

int main()
{
	Grammar g;
	g.init();

	if (g.have_left_recursion())
	{
		cout << "输入产生式中含有左递归式,尝试进行修改\n";
		g.first_letter_substitution();
		g.printProduction();
		g.parsing_direct_left_recursion();
		g.del_unreachable_production();
		cout << "提取左递归式后的产生式集合如下:\n\n";
		g.printProduction();
	}

	if (g.have_common_factor())
	{
		cout << "输入产生式中含有左公因式,尝试进行修改\n";
		g.first_letter_substitution();
		g.parsing_common_factor();
		g.del_unreachable_production();
		cout << "提取左公因式后的产生式集合如下:\n\n";
		g.printProduction();
	}

	g.cal_First();

	g.printFirst();

	// 计算Follow集合
	g.cal_Follow();
	g.printFollow();

	// 计算Select集合
	g.cal_Select();
	g.printSelect();

	if (g.is_LL1())
	{
		g.printTable();
		if (g.grammar_parsing())
		{
			cout << "句子匹配成功\n";
		}
	}
	else
	{
		cout << "输入文法不是LL(1)型文法\n";
	}

	system("pause");

	return 0;
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值