编译原理LL1语法分析程序

#pragma once
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#include <fstream>
#include <stack>
#include <string>


void PrintAnalysisTable(std::map<std::string, std::map<std::string, std::string>> analysisTable,
	const std::vector<std::string>& terminatorList,
	const std::vector<std::string>& nonterminalList);

void InitAnalysisTable(std::map<std::string, std::map<std::string, std::string>>& analysisTable,
	const std::vector<std::string>& terminatorList, const std::vector<std::string>& nonterminalList);

std::string GetSartCharByCandidate(std::string candidate, std::map<std::string, std::set<std::string>> allRightMap);

void ConstructorAnalysisTableByFirst(
	std::map<std::string, std::map<std::string, std::string>>& analysisTable,
	std::map<std::string, std::set<std::string>> First,
	std::map<std::string, std::set<std::string>> Follow,
	std::map<std::string, std::set<std::string>> allRightMap,
	const std::vector<std::string>& nonterminalList
);

void ConstructorAnalysisTableByFollow(
	std::map<std::string, std::map<std::string, std::string>>& analysisTable,
	std::map<std::string, std::set<std::string>> Follow,
	std::map<std::string, std::set<std::string>> allRightMap,
	const std::vector<std::string>& nonterminalList);


std::map<std::string, std::map<std::string, std::string>> AnalysisTableConstructor(
	std::map<std::string, std::set<std::string>> First,
	std::map<std::string, std::set<std::string>> Follow,
	const std::vector<std::string>& terminatorList,
	const std::vector<std::string>& nonterminalList,
	std::map<std::string, std::set<std::string>> allRightMap);

// 分割一条文法的左部和右部
std::vector<std::string> GetOneLeft_Right(const std::string oneGrammer);

// 获取所有文法的左部和右部
void GetLeft_RightList(const std::vector<std::string>& grammarList, std::vector<std::vector<std::string>>& left_rightList);

// 打印全部文法分割完成的状态
void PrintLeft_RightList(const std::vector<std::vector<std::string>>& left_rightList);

// 读取文法 TXT 文件
void ReadGrammerFile(std::vector<std::string>& grammarList, std::string url);

// 打印全部的文法
void PrintGrammerList(const std::vector<std::string>& grammarList);

// 是否存在左递归。如果存在,返回是第几个候选式
bool LeftRecursion(const std::vector<std::string>& left_right);

// 找到所有左递归的文法索引及其是第几个侯选式出现左递归的索引对
std::vector<std::pair<int, int>> GetPairIndex(const std::vector<std::vector<std::string>> left_rightList);

// 消除一条文法左递归
void EliminateOneLeftRecursion(std::vector<std::string>& grammarList, const std::vector<std::vector<std::string>> left_rightList, std::vector<std::string>& left_right, std::pair<int, int> pairIndex, int ii);

// 消除全部文法左递归
void EliminateAllLeftRecursion(std::vector<std::string>& grammarList, std::vector<std::vector<std::string>>& left_rightList);

// 获取句型的首字符
std::string GetFirstChar2(std::string sentence);

void SetFirstGrammar(std::vector<std::string>& grammarList, std::string startCh);

void EliminateLeftRecursion(std::vector<std::string>& grammarList);


// *************************************************************************************************

void PairSetToVector(std::vector<std::pair<std::string, std::string>>& v, std::set<std::pair<std::string, std::string>>& s);

// 获取句型的首字符
std::string GetFirstChar(std::string sentence);


// 根据开始符号确定文法
std::vector<std::string> GetGrammar(std::string firstChar, const std::vector<std::string>& grammarList);

void GetRightString(const std::vector<std::string>& grammarList, std::vector<std::string>& rightStringList);

// 打印产生式右侧的符号串
void PrintRightString(const std::vector<std::string>& rightString);

// 输入:句型和全部文法
// 返回:该句型的 FIRST 集
void GetOneFirst(std::string& sentence, std::vector<std::string>& First, const std::vector<std::string>& grammarList,
	const std::vector<std::string>& terminator, const std::vector<std::string>& nonterminal);

void PrintOneFirst(std::string sentence, std::vector<std::string>& First);

void GetAllSentence(std::vector<std::string>& allSentence, const std::vector<std::string>& allLeftList,
	std::vector<std::string>& allRightList);

void PrintAllSentence(const std::vector<std::string>& allSentence);

std::map<std::string, std::set<std::string>> GetFirstSet(const std::vector<std::string>& allSentenceList,
	const std::vector<std::string>& grammarList, const std::vector<std::string>& terminatorList,
	const std::vector<std::string>& nonterminalList);

void PrintFirst22(std::map<std::string, std::set<std::string>>& First);

// *************************************************************************************************

 // 输入侯选式返回文法开始符号 
std::vector<std::string> GetCandidateStartChar(const std::string candidate, const std::vector<std::string>& nonterminalList, std::map<std::string, std::set<std::string>> left_Right);

int GetNonterminalIndex(std::string oneNonterminal, const std::vector<std::string>& nonterminalList);


// 获取一条产生式全部的右部的侯选式
std::vector<std::string> GetOneGrammarAllRight(std::string oneGrammar);

// 获取全部文法的全部右部
std::vector<std::string> GetGrammarAllRight(std::map<std::string, std::set<std::string>> left_Right, const std::vector<std::string>& nonterminalList);

// 获取一条侯选式的全部字符
std::vector<std::string> GetOneCandidateAllCharacter(std::string str);

// 寻找一条侯选式的 B 和 Beta
std::vector<std::pair<std::string, std::string>> FindAlphaBeta(std::string oneRight, const std::vector<std::string>& nonterminal, const std::vector<std::string>& allCharacter);

// 寻找全部侯选式的 B 和 Beta
std::vector<std::pair<std::string, std::string>> FindAllAlphaBeta(std::vector<std::string> allRight, const std::vector<std::string>& nonterminal);

// 求解 FOLLOW 集合 规则一
void Rule1(std::map<std::string, std::set<std::string>>& Follow, const std::vector<std::string>& grammarList);

// 求解 FOLLOW 集合 规则二
void Rule2(std::map<std::string, std::set<std::string>>& Follow, std::vector<std::pair<std::string, std::string>> allB_Beta, const std::vector<std::string>& grammarList,
	const std::vector<std::string>& terminator, const std::vector<std::string>& nonterminal);

// beta 是否能广义推导出 空符号
void IsGeneralizedDerivation(std::string lastA, std::pair<std::string, std::string>& B_Beta, std::map<std::string, std::set<std::string>> left_Right, const std::vector<std::string>& terminator, bool& flag, std::set<std::string>& ASet);



// 规则三递归终止条件
bool IsRule3Over(std::map<std::string, std::set<std::string>>& Follow, std::map<std::string, std::set<std::string>>& Follow2, const std::vector<std::string>& nonterminal);

// 求解 FOLLOW 集合 规则三
void Rule3(std::map<std::string, std::set<std::string>>& Follow, const std::vector<std::string>& allRight, std::map<std::string, std::set<std::string>> left_Right, const std::vector<std::string>& grammarList,
	const std::vector<std::string>& terminator, const std::vector<std::string>& nonterminal);

std::map<std::string, std::set<std::string>> GetFollowSet(std::vector<std::string>& grammarList);

int PrintFollow(std::map<std::string, std::set<std::string>>& Follow);

// *************************************************************************************************

// 向栈中插入符号串
void MyPush(std::stack<std::string>& analysisStack, std::string string0);

// 打印栈中的元素
void PrintStack(const std::stack<std::string>& analysisStack);


// 初始化符号串栈
void InitStringStack(std::stack<std::string>& stringStack, std::string string0);

// 初始化分析栈
void InitAnalysisStack(std::stack<std::string>& analysisStack, std::string startChar);

// 根据两个栈顶元素查表返回表格中的值
std::string GetGrammar(std::string analysisTop,
	std::string stringTop, std::map<std::string,
	std::map<std::string, std::string>> analysisTable);

// 根据一条产生式返回他的右部
std::string GetRight(std::string oneGrammar);


std::vector<std::vector<std::string>> Func(std::stack<std::string>& analysisStack,
	std::stack<std::string>& stringStack,
	std::map<std::string,
	std::map<std::string, std::string>> analysisTable,
	int& step);


std::vector<std::vector<std::string>> StringAnalysis(std::string string0,
	std::string startChar, std::map<std::string, std::map<std::string,
	std::string>> analysisTable);

// 打印符号串分析的全部过程
void PrintAllStep(const std::vector<std::vector<std::string>>& allStep, std::string string0);

// *************************************************************************************************

void GetOneLeft_Right2(const std::string oneGrammer, std::map<std::string, std::set<std::string>>& left_Right);

void GetAllRightMap(std::map<std::string, std::set<std::string>>& left_Right, const std::vector<std::string> grammarList);

void PrintLeft_Right2(std::map<std::string, std::set<std::string>>& left_Right);

// 判断是否是终结符号
bool IsTerminator(std::string ch, const std::vector<std::string>& terminator);

// 判断是否是非终结符号
bool IsNonterminal(std::string ch, const std::vector<std::string>& nonterminal);

void PrintTerminator(const std::vector<std::string>& terminatorList);


void PrintNonterminal(const std::vector<std::string>& nonterminalList);

// 将去重的 set 集合 赋值给 vector 集合
void SetToVector(std::vector<std::string>& v, const std::set<std::string>& s);

// 求解终结符号集 和 非终结符号集
void GetTerminator_Nonterminal(const std::vector<std::string>& grammarList,
	std::vector<std::string>& terminatorList,
	std::vector<std::string>& nonterminalList);

// *************************************************************************************************


std::string GetSartCharByCandidate(std::string candidate, std::map<std::string, std::set<std::string>> allRightMap)
{
    
    
	std::string startChar;
	for (std::pair<std::string, std::set<std::string>> oneGrammarRight : allRightMap)
	{
    
    
		startChar = oneGrammarRight.first;
		for (std::string right : oneGrammarRight.second)
		{
    
    
			if (right == candidate)
			{
    
    
				return startChar;
			}
		}
	}
	std::cout << "出错了" << std::endl;
	return "Error";
}

void PrintAnalysisTable(std::map<std::string, std::map<std::string, std::string>> analysisTable,
	const std::vector<std::string>& terminatorList,
	const std::vector<std::string>& nonterminalList)
{
    
    
	std::vector<std::string> ROW = nonterminalList;
	std::vector<std::string> COL = terminatorList;
	for (int i = 0; i < COL.size(); i++)
	{
    
    
		if (COL[i] == "$")
		{
    
    
			COL[i] = "#";
			break;
		}
	}
	std::cout << "LL(1) 分析表如下" << std::endl;
	std::string j;
	std::cout << std::left <<  "     |" << std::left << std::setw(6) << "";
	for (int k = COL.size() - 1; k >= 0; k--)
	{
    
    
		std::cout << std::left << std::setw(10) << COL[k];
	}
	std::cout << std::endl;
	int num = COL.size() + 1;
	std::string space = "----------";
	for (int i = 0; i < num; i++)
	{
    
    
		std::cout << std::left << std::setw(10) << space;
	}
	std::cout << std::endl;
	for (std::string i : ROW)
	{
    
    
		std::cout << std::left << std::setw(5) << i << std::left << std::setw(5) << "|";
		for (int k = COL.size() - 1; k>=0; k--)
		{
    
    
			j = COL[k];
			std::cout << std::left << std::setw(10) << analysisTable[i][j];
		}
		std::cout << std::endl;
	}
	std::cout << std::endl;
}


// 由 FIRST 集构造分析表
void ConstructorAnalysisTableByFirst(
	std::map<std::string, std::map<std::string, std::string>>& analysisTable,
	std::map<std::string, std::set<std::string>> First,
	std::map<std::string, std::set<std::string>> Follow,
	std::map<std::string, std::set<std::string>> allRightMap,
	const std::vector<std::string>& nonterminalList)
{
    
    

	for (std::pair<std::string, std::set<std::string>> first : First)
	{
    
    
		std::string right = first.first;
		if (IsNonterminal(right, nonterminalList) || right == "$")
		{
    
    
			continue;
		}
		for (std::string item : first.second)
		{
    
    
			std::string startChar = GetSartCharByCandidate(right, allRightMap);
			std::string i = startChar;
			std::string j = item;
			std::string grammar = startChar + "->" + right;
			analysisTable[i][j] = grammar;
		}
	}
}


// 由 FOLLOW 集构造分析表
void ConstructorAnalysisTableByFollow(
	std::map<std::string, std::map<std::string, std::string>>& analysisTable,
	std::map<std::string, std::set<std::string>> Follow,
	std::map<std::string, std::set<std::string>> allRightMap,
	const std::vector<std::string>& nonterminalList)
{
    
    

	for (std::pair<std::string, std::set<std::string>> left_rightSet : allRightMap)
	{
    
    
		std::string left = left_rightSet.first;
		std::set<std::string> rightSet = left_rightSet.second;
		for (std::string right : rightSet)
		{
    
    
			if (right == "$")
			{
    
    
				std::string i = left;
				auto indexList = Follow[left];
				for (std::string j : indexList)
				{
    
    
					std::string grammar = left + "->$";
					analysisTable[i][j] = grammar;
				}
			}
		}
	}
}

void InitAnalysisTable(std::map<std::string, std::map<std::string, std::string>>& analysisTable,
	const std::vector<std::string>& ROW, const std::vector<std::string>& COL)
{
    
    
	for (std::string i : ROW)
	{
    
    
		for (std::string j : COL)
		{
    
    
			analysisTable[i][j] = "";
		}
	}
}



std::map<std::string, std::map<std::string, std::string>> AnalysisTableConstructor(
	std::map<std::string, std::set<std::string>> First,
	std::map<std::string, std::set<std::string>> Follow,
	const std::vector<std::string>& terminatorList,
	const std::vector<std::string>& nonterminalList,
	std::map<std::string, std::set<std::string>> allRightMap)
{
    
    
	std::map<std::string, std::map<std::string, std::string>>  analysisTable;

	std::vector<std::string> ROW = nonterminalList;
	std::vector<std::string> COL = terminatorList;
	for (int i = 0; i < COL.size(); i++)
	{
    
    
		if (COL[i] == "$")
		{
    
    
			COL[i] = "#";
			break;
		}
	}

	//PrintTerminator(COL);

	InitAnalysisTable(analysisTable, ROW, COL);

	ConstructorAnalysisTableByFirst(analysisTable, First, Follow, allRightMap, nonterminalList);
	ConstructorAnalysisTableByFollow(analysisTable, Follow, allRightMap, nonterminalList);

	

	return analysisTable;
}

// *************************************************************************************************

// 分割一条文法的左部和右部
std::vector<std::string> GetOneLeft_Right(const std::string oneGrammer)
{
    
    
	std::vector<std::string> left_right;
	std::string word = "";
	word = oneGrammer.substr(0, 1);

	int i = 4;

	if (oneGrammer.substr(1, 1) == "'")
	{
    
    
		i++;
		word += oneGrammer.substr(1, 1);
	}

	left_right.push_back(word);

	word = "";

	for (; i < oneGrammer.length(); i++)
	{
    
    
		if (oneGrammer[i] == '|')
		{
    
    
			left_right.push_back(word);
			word = "";
			continue;
		}
		word += oneGrammer[i];
	}
	left_right.push_back(word);

	
	return left_right;
}

// 获取所有文法的左部和右部
void GetLeft_RightList(const std::vector<std::string>& grammarList, std::vector<std::vector<std::string>>& left_rightList)
{
    
    
	for (std::string oneGrammer : grammarList)
	{
    
    
		left_rightList.push_back(GetOneLeft_Right(oneGrammer));
	}
}

// 打印全部文法分割完成的状态
void PrintLeft_RightList(const std::vector<std::vector<std::string>>& left_rightList)
{
    
    
	for (std::vector<std::string> left_right : left_rightList)
	{
    
    
		for (std::string part : left_right)
		{
    
    
			std::cout << part << " ";
		}
		std::cout << std::endl;
	}
}

// 读取文法 TXT 文件
void ReadGrammerFile(std::vector<std::string>& grammarList, std::string url)
{
    
    
	std::ifstream in(url);
	std::string filename;
	std::string line;

	if (in) // 有该文件
	{
    
    
		while (std::getline(in, line)) // line中不包括每行的换行符
		{
    
    
			grammarList.push_back(line);
		}
	}
}

// 打印全部的文法
void PrintGrammerList(const std::vector<std::string>& grammarList)
{
    
    
	for (std::string a : grammarList)
	{
    
    
		std::cout << a << std::endl;
	}

	std::cout << std::endl;
}

// 是否存在左递归。如果存在,返回是第几个候选式
bool LeftRecursion(const std::vector<std::string>& left_right)
{
    
    
	std::string left = left_right[0];
	for (int i = 1; i < left_right.size(); i++)
	{
    
    
		if (left == (left_right[i]).substr(0, 1))
		{
    
    
			return i;
		}
	}
	return 0;
}

// 找到所有左递归的文法索引及其是第几个侯选式出现左递归的索引对
std::vector<std::pair<int, int>> GetPairIndex(const std::vector<std::vector<std::string>> left_rightList)
{
    
    
	std::vector<std::pair<int, int>> leftRecursionIndex;
	for (int i = 0; i < left_rightList.size(); i++)
	{
    
    
		if (int j = LeftRecursion(left_rightList[i]))
		{
    
    
			leftRecursionIndex.push_back(std::make_pair(i, j));
		}
	}
	return leftRecursionIndex;
}

// 消除一条文法左递归
void EliminateOneLeftRecursion(std::vector<std::string>& grammarList, const std::vector<std::vector<std::string>> left_rightList, std::vector<std::string>& left_right, std::pair<int, int> pairIndex, int ii)
{
    
    
	// 左部
	std::string A = left_right[0];
	int grammerIndex = pairIndex.first;
	int leftRecursionIndex = pairIndex.second;
	// 左递归部分的长度
	int partLength = left_right[leftRecursionIndex].length();
	std::string alpha = left_right[leftRecursionIndex].substr(1, partLength);
	std::string beta = left_right[3 - leftRecursionIndex];

	//std::cout << "alpha = " << alpha << "\nbeta = " << beta << std::endl;

	//std::cout << "\n\n";

	grammarList.erase(grammarList.begin() + grammerIndex - ii); // 该处erase处理方法
	std::string grammer1 = A + "::=" + beta + A + "'";
	std::string grammer2 = A + "'::=" + alpha + A + "'|$";
	grammarList.push_back(grammer1);
	grammarList.push_back(grammer2);
}

// 消除全部文法左递归
void EliminateAllLeftRecursion(std::vector<std::string>& grammarList, std::vector<std::vector<std::string>>& left_rightList)
{
    
    
	// 索引对
	std::vector<std::pair<int, int>> pairIndex = GetPairIndex(left_rightList);
	for (int i = 0; i < pairIndex.size(); i++)
	{
    
    
		EliminateOneLeftRecursion(grammarList, left_rightList, left_rightList[pairIndex[i].first], pairIndex[i], i);
	}
}

// 获取句型的首字符
std::string GetFirstChar2(std::string sentence)
{
    
    
	std::string firstChar = sentence.substr(0, 1);
	if (sentence.length() > 1 && sentence.substr(1, 1) == "'")
	{
    
    
		firstChar = sentence.substr(0, 2);
	}
	return firstChar;
}

void SetFirstGrammar(std::vector<std::string>& grammarList, std::string startCh)
{
    
    
	std::string oneGrammar = grammarList[0];
	std::string firstChar = GetFirstChar2(oneGrammar);
	if (firstChar == startCh)
	{
    
    
		return;
	}
	for (int i = 1; i < grammarList.size(); i++)
	{
    
    
		oneGrammar = grammarList[i];
		firstChar = GetFirstChar2(oneGrammar);
		if (firstChar == startCh)
		{
    
    
			grammarList[i] = grammarList[0];
			grammarList[0] = oneGrammar;
			break;
		}
	}
}

void EliminateLeftRecursion(std::vector<std::string>& grammarList)
{
    
    
	std::vector<std::vector<std::string>> left_rightList;   // 文法分为左部和多个右部列表

	std::string startChar = GetFirstChar2(grammarList[0]);

	GetLeft_RightList(grammarList, left_rightList);

	EliminateAllLeftRecursion(grammarList, left_rightList);

	SetFirstGrammar(grammarList, startChar);
}

// *************************************************************************************************
void PairSetToVector(std::vector<std::pair<std::string, std::string>>& v, std::set<std::pair<std::string, std::string>>& s)
{
    
    
	v.clear();
	for (std::pair<std::string, std::string> item : s)
	{
    
    
		v.push_back(item);
	}
}

// 获取句型的首字符
std::string GetFirstChar(std::string sentence)
{
    
    
	std::string firstChar = sentence.substr(0, 1);
	if (sentence.length() > 1 && sentence.substr(1, 1) == "'")
	{
    
    
		firstChar = sentence.substr(0, 2);
	}
	return firstChar;
}

// 根据开始符号确定文法
std::vector<std::string> GetGrammar(std::string firstChar, const std::vector<std::string>& grammarList)
{
    
    
	int grammarIndex;
	std::string grammar;
	std::vector<std::string> rightString;
	for (grammarIndex = 0; grammarIndex < grammarList.size(); grammarIndex++)
	{
    
    
		if (firstChar == grammarList[grammarIndex].substr(0, firstChar.length()))
		{
    
    
			break;
		}
	}

	std::vector<std::string> left_right = GetOneLeft_Right(grammarList[grammarIndex]);
	// 把最左边的消除,只剩产生式的右侧
	left_right.erase(left_right.begin());
	return left_right;
}

void GetRightString(const std::vector<std::string>& grammarList, std::vector<std::string>& rightStringList)
{
    
    
	std::set<std::string> rightStringSet;
	std::vector<std::vector<std::string>> left_rightList;
	GetLeft_RightList(grammarList, left_rightList);
	for (std::vector<std::string> item : left_rightList)
	{
    
    
		for (int i = 1; i < item.size(); i++)
		{
    
    
			rightStringSet.insert(item[i]);
		}
	}
	SetToVector(rightStringList, rightStringSet);
}

// 打印产生式右侧的符号串
void PrintRightString(const std::vector<std::string>& rightString)
{
    
    
	for (std::string item : rightString)
	{
    
    
		std::cout << item << " ";
	}
}

// 输入:句型和全部文法
// 返回:该句型的 FIRST 集
void GetOneFirst(std::string& sentence, std::vector<std::string>& First, const std::vector<std::string>& grammarList,
	const std::vector<std::string>& terminator, const std::vector<std::string>& nonterminal)
{
    
    
	std::string firstChar = GetFirstChar(sentence);
	if (IsTerminator(firstChar, terminator))
	{
    
    
		First.push_back(firstChar);
		return;
	}
	else
	{
    
    
		std::vector<std::string> rightList = GetGrammar(firstChar, grammarList);
		for (std::string item : rightList)
		{
    
    
			sentence = item + sentence.substr(firstChar.length(), sentence.length() - firstChar.length());
			GetOneFirst(sentence, First, grammarList, terminator, nonterminal);
		}
	}

}

void PrintOneFirst(std::string sentence, std::vector<std::string>& First)
{
    
    
	std::cout << sentence << ": {";
	for (auto ii : First)
	{
    
    
		std::cout << ii << ", ";
	}
	std::cout << "\b\b}" << std::endl;
}

void GetAllSentence(std::vector<std::string>& allSentenceList, const std::vector<std::string>& allLeftList,
	std::vector<std::string>& allRightList)
{
    
    
	for (std::string item : allLeftList)
	{
    
    
		allSentenceList.push_back(item);
	}
	for (std::string item : allRightList)
	{
    
    
		allSentenceList.push_back(item);
	}
}

void PrintAllSentence(const std::vector<std::string>& allSentence)
{
    
    
	for (std::string item : allSentence)
	{
    
    
		std::cout << item << "  " << std::endl;
	}
}


std::map<std::string, std::set<std::string>> GetFirstSet(const std::vector<std::string>& allSentenceList,
	const std::vector<std::string>& grammarList, const std::vector<std::string>& terminatorList,
	const std::vector<std::string>& nonterminalList)
{
    
    
	std::map<std::string, std::set<std::string>> First;
	std::vector<std::string> oneFirst;
	for (std::string sentence : allSentenceList)
	{
    
    
		std::string sentenceTemp = sentence;
		oneFirst.clear();
		GetOneFirst(sentence, oneFirst, grammarList, terminatorList, nonterminalList);
		for (std::string item : oneFirst)
		{
    
    
			First[sentenceTemp].insert(item);
		}
	}
	return First;
}

void PrintFirst22(std::map<std::string, std::set<std::string>>& First)
{
    
    
	std::cout << "FIRST 集如下" << std::endl;
	for (std::pair<std::string, std::set<std::string>> item : First)
	{
    
    
		std::cout << item.first << ": {";
		for (std::string ii : item.second)
		{
    
    
			std::cout << ii << ", ";
		}
		std::cout << "\b\b}" << std::endl;
	}
	std::cout << std::endl;
}

// *************************************************************************************************

// 输入侯选式返回文法开始符号 
std::vector<std::string> GetCandidateStartChar(const std::string candidate, const std::vector<std::string>& nonterminalList, std::map<std::string, std::set<std::string>> left_Right)
{
    
    
	std::vector<std::string> startCharList;
	for (std::string key : nonterminalList)
	{
    
    
		for (std::string item : left_Right[key])
		{
    
    
			if (item == candidate)
			{
    
    
				startCharList.push_back(key);
				break;
			}
		}
	}
	return startCharList;
}

int GetNonterminalIndex(std::string oneNonterminal, const std::vector<std::string>& nonterminalList)
{
    
    
	for (int i = 0; i < nonterminalList.size(); i++)
	{
    
    
		if (oneNonterminal == nonterminalList.at(i));
		{
    
    
			return i;
		}
	}
	std::cout << "寻找非终结符号出错" << std::endl;
	return -1;
}

// 获取一条产生式全部的右部的侯选式
std::vector<std::string> GetOneGrammarAllRight(std::string oneGrammar)
{
    
    
	std::vector<std::string> right;
	std::string word = "";
	word = oneGrammar.substr(0, 1);

	int i = 4;

	if (oneGrammar.substr(1, 1) == "'")
	{
    
    
		i++;
		word += oneGrammar.substr(1, 1);
	}

	word = "";

	for (; i < oneGrammar.length(); i++)
	{
    
    
		if (oneGrammar[i] == '|')
		{
    
    
			right.push_back(word);
			word = "";
			continue;
		}
		word += oneGrammar[i];
	}
	right.push_back(word);
	return right;
}

// 获取全部文法的全部右部
std::vector<std::string> GetGrammarAllRight(std::map<std::string, std::set<std::string>> left_Right, const std::vector<std::string>& nonterminalList)
{
    
    
	std::vector<std::string> allRightList;
	std::set<std::string> allRightSet;
	for (std::string key : nonterminalList)
	{
    
    
		for (std::string item : left_Right[key])
			allRightSet.insert(item);
	}
	SetToVector(allRightList, allRightSet);
	return allRightList;
}

// 获取一条侯选式的全部字符
std::vector<std::string> GetOneCandidateAllCharacter(std::string str)
{
    
    
	std::vector<std::string> characterList;
	std::string ch;
	for (int i = 0; i < str.size(); i++)
	{
    
    
		ch = str.substr(i, 1);
		if (i < str.size() - 1 && str.substr(i + 1, 1) == "'")
		{
    
    
			ch += "'";
			i++;
		}
		characterList.push_back(ch);
	}
	return characterList;
}

// 寻找一条侯选式的 B 和 Beta
std::vector<std::pair<std::string, std::string>> FindAlphaBeta(std::string oneRight, const std::vector<std::string>& nonterminal, const std::vector<std::string>& allCharacter)
{
    
    
	std::vector<std::pair<std::string, std::string>> B_BetaList;
	int index = 0;
	int chNum = allCharacter.size();
	std::string beta;
	for (int i = 0; i < chNum; i++)
	{
    
    
		index += allCharacter.at(i).length();
		if (IsNonterminal(allCharacter.at(i), nonterminal))
		{
    
    
			std::string B = allCharacter.at(i);
			beta = oneRight.substr(index);
			beta = beta.size() == 0 ? "$" : beta;
			B_BetaList.push_back(make_pair(B, beta));
		}
	}
	return B_BetaList;
}

// 寻找全部侯选式的 B 和 Beta
std::vector<std::pair<std::string, std::string>> FindAllAlphaBeta(std::vector<std::string> allRight, const std::vector<std::string>& nonterminal)
{
    
    
	std::set<std::pair<std::string, std::string>> allB_BetaSet;
	std::vector<std::pair<std::string, std::string>> allB_BetaList;
	std::vector<std::string> allCharacter;
	for (std::string oneRight : allRight)
	{
    
    
		allCharacter = GetOneCandidateAllCharacter(oneRight);
		std::vector<std::pair<std::string, std::string>> T = FindAlphaBeta(oneRight, nonterminal, allCharacter);
		for (std::pair<std::string, std::string> item : T)
		{
    
    
			allB_BetaSet.insert(item);
		}
	}
	PairSetToVector(allB_BetaList, allB_BetaSet);
	return allB_BetaList;
}

// 求解 FOLLOW 集合 规则一
void Rule1(std::map<std::string, std::set<std::string>>& Follow, const std::vector<std::string>& grammarList)
{
    
    
	std::string startChar = GetFirstChar(grammarList[0]);
	Follow[startChar].insert("#");
}

// 求解 FOLLOW 集合 规则二
void Rule2(std::map<std::string, std::set<std::string>>& Follow, std::vector<std::pair<std::string, std::string>> allB_Beta, const std::vector<std::string>& grammarList,
	const std::vector<std::string>& terminator, const std::vector<std::string>& nonterminal)
{
    
    
	std::vector<std::string> First;
	for (std::pair<std::string, std::string> B_Beta : allB_Beta)
	{
    
    
		First.clear();
		std::string B = B_Beta.first;
		std::string beta = B_Beta.second;

		GetOneFirst(beta, First, grammarList, terminator, nonterminal);
		for (std::string item : First)
		{
    
    
			if (item != "$")
			{
    
    
				Follow[B].insert(item);
			}
		}
	}
}

// beta 是否能广义推导出 空符号
void IsGeneralizedDerivation(std::string lastA, std::pair<std::string, std::string>& B_Beta, std::map<std::string, std::set<std::string>> left_Right, const std::vector<std::string>& terminator, bool& flag, std::set<std::string>& ASet)
{
    
    
	std::string beta = B_Beta.second;

	std::string firstCh = GetFirstChar(beta);



	if (IsTerminator(firstCh, terminator))
	{
    
    
		if (firstCh == "$")
		{
    
    
			flag = true;
			ASet.insert(lastA);
		}
		return;

	}
	else
	{
    
    
		for (std::string right : left_Right[firstCh])
		{
    
    
			std::string newBeta = right + beta.substr(firstCh.size());
			B_Beta.second = newBeta;
			lastA = firstCh;
			IsGeneralizedDerivation(lastA, B_Beta, left_Right, terminator, flag, ASet);
		}
	}
}

// 规则三递归终止条件
bool IsRule3Over(std::map<std::string, std::set<std::string>>& Follow, std::map<std::string, std::set<std::string>>& Follow2, const std::vector<std::string>& nonterminal)
{
    
    
	for (std::string key : nonterminal)
	{
    
    
		if (Follow[key].size() != Follow2[key].size())
		{
    
    
			return false;
		}
	}
	return true;
}

// 求解 FOLLOW 集合 规则三
void Rule3(std::map<std::string, std::set<std::string>>& Follow, const std::vector<std::string>& allRight, std::map<std::string, std::set<std::string>> left_Right, const std::vector<std::string>& grammarList,
	const std::vector<std::string>& terminator, const std::vector<std::string>& nonterminal)
{
    
    
	std::map<std::string, std::set<std::string>> tempFollow = Follow;
	bool flag;
	for (std::string oneRight : allRight)
	{
    
    
		std::vector<std::string> allChar = GetOneCandidateAllCharacter(oneRight);
		std::vector<std::pair<std::string, std::string>> allB_Beta = FindAlphaBeta(oneRight, nonterminal, allChar);
		std::vector<std::string> startCharList = GetCandidateStartChar(oneRight, nonterminal, left_Right);
		for (std::pair<std::string, std::string> B_Beta : allB_Beta)
		{
    
    
			for (std::string startChar : startCharList)
			{
    
    
				std::set<std::string> ASet;
				flag = false;
				std::string B = B_Beta.first;
				std::string beta = B_Beta.second;
				std::string firstCh = startChar;
				IsGeneralizedDerivation(firstCh, B_Beta, left_Right, terminator, flag, ASet);
				if (flag)
				{
    
    
					for (std::string key : ASet)
					{
    
    
						//std::cout << "A = " << key << "  ";
						//std::cout << key << " ";
						for (std::string item : Follow[key])
						{
    
    
							Follow[B].insert(item);
						}
					}
					//std::cout << "属于" << B << std::endl;
				}
			}
		}
	}
	// 如果更新了,则继续递归;否则如果本次没有更新,继续递归
	if (!IsRule3Over(Follow, tempFollow, nonterminal))
	{
    
    
		Rule3(Follow, allRight, left_Right, grammarList, terminator, nonterminal);
	}
}

// 求解 Follow集 主函数
std::map<std::string, std::set<std::string>> GetFollowSet(std::vector<std::string>& grammarList)
{
    
    
	std::vector<std::string> terminatorList;
	std::vector<std::string> nonterminalList;

	std::map<std::string, std::set<std::string>> left_Right;

	std::map<std::string, std::set<std::string>> Follow;

	std::vector<std::pair<std::string, std::string>> allB_Beta;



	GetTerminator_Nonterminal(grammarList, terminatorList, nonterminalList);

	GetAllRightMap(left_Right, grammarList);


	std::vector<std::string> allRight = GetGrammarAllRight(left_Right, nonterminalList);



	allB_Beta = FindAllAlphaBeta(allRight, nonterminalList);

	Rule1(Follow, grammarList);

	//std::cout << "规则一" << std::endl;
	//PrintFollow(Follow);

	Rule2(Follow, allB_Beta, grammarList, terminatorList, nonterminalList);

	//std::cout << "规则二" << std::endl;
	//PrintFollow(Follow);

	Rule3(Follow, allRight, left_Right, grammarList, terminatorList, nonterminalList);

	//std::cout << "规则三" << std::endl;


	return Follow;
}

int PrintFollow(std::map<std::string, std::set<std::string>>& Follow)
{
    
    
	std::cout << "FOLLOW 集如下" << std::endl;
	for (std::pair<std::string, std::set<std::string>> item : Follow)
	{
    
    
		std::cout << item.first << ": {";
		for (std::string ii : item.second)
		{
    
    
			std::cout << ii << ", ";
		}
		std::cout << "\b\b}" << std::endl;
	}
	std::cout << std::endl;
	return 0;
}

// *************************************************************************************************

void MyPush(std::stack<std::string>& analysisStack, std::string string0)
{
    
    
	std::vector<std::string> charList;
	std::string ch;
	int len = string0.length();
	for (int i = 0; i < len; i++)
	{
    
    
		ch = string0.substr(i, 1);
		if (i + 1 < len && string0.substr(i + 1, 1) == "'")
		{
    
    
			ch = string0.substr(i, 2);
			i++;
		}
		charList.push_back(ch);
	}
	for (int i = charList.size() - 1; i >= 0; i--)
	{
    
    
		analysisStack.push(charList[i]);
	}
}

std::string GetAnalysisByStack(const std::stack<std::string>& analysisStack)
{
    
    
	std::stack<std::string> tempAnalysisStack = analysisStack;
	std::vector<std::string> charList;
	std::string string0;
	int size = tempAnalysisStack.size();
	for (int i = 0; i < size; i++)
	{
    
    
		charList.push_back(tempAnalysisStack.top());
		tempAnalysisStack.pop();
	}
	for (int i = charList.size() - 1; i >= 0; i--)
	{
    
    
		string0 += charList[i];
	}
	return string0;

}

std::string GetStringByStack(const std::stack<std::string>& stringStack)
{
    
    
	std::stack<std::string> tempStringStack = stringStack;
	std::string string0;
	int size = tempStringStack.size();
	for (int i = 0; i < size; i++)
	{
    
    
		string0 += tempStringStack.top();
		tempStringStack.pop();
	}
	return string0;
}

void PrintStack(const std::stack<std::string>& analysisStack)
{
    
    
	std::stack<std::string> tempStack = analysisStack;
	while (tempStack.size() != 0)
	{
    
    
		std::string ch = tempStack.top();
		tempStack.pop();
		std::cout << ch << std::endl;
	}
}



void InitStringStack(std::stack<std::string>& stringStack, std::string string0)
{
    
    
	stringStack.push("#");
	MyPush(stringStack, string0);
}

void InitAnalysisStack(std::stack<std::string>& analysisStack, std::string startChar)
{
    
    
	analysisStack.push("#");
	analysisStack.push(startChar);
}

// 
std::string GetGrammar(std::string analysisTop, std::string stringTop, std::map<std::string, std::map<std::string, std::string>> analysisTable)
{
    
    
	return analysisTable[analysisTop][stringTop];
}


void PrintAllStep(const std::vector<std::vector<std::string>>& allStep, std::string string0)
{
    
    
	std::cout << "符号串 " << string0 << " 的分析过程" << std::endl;
	for (std::vector<std::string> oneStep : allStep)
	{
    
    
		std::cout << std::left << std::setw(6) << oneStep[0]
			<< std::left << std::setw(10) << oneStep[1]
			<< std::right << std::setw(10) << oneStep[2] << "     "
			<< std::left << std::setw(10) << oneStep[3]
			<< std::endl;

	}
}

std::string GetRight(std::string oneGrammar)
{
    
    
	std::string firstChar = oneGrammar.substr(0, 1);
	std::string right;
	if (oneGrammar.substr(1, 1) == "'")
	{
    
    
		firstChar = oneGrammar.substr(0, 2);
	}
	if (oneGrammar.substr(firstChar.length(), 3) == "::=")
	{
    
    
		right = oneGrammar.substr(firstChar.length() + 3);
		return right;
	}
	else if (oneGrammar.substr(firstChar.length(), 2) == "->")
	{
    
    
		right = oneGrammar.substr(firstChar.length() + 2);
		return right;
	}
	else
	{
    
    
		std::cout << "right 出错了" << std::endl;
		return "";
	}

}

std::vector<std::vector<std::string>> Func(std::stack<std::string>& analysisStack, std::stack<std::string>& stringStack, std::map<std::string, std::map<std::string, std::string>> analysisTable, int& step)
{
    
    
	std::string analysisTop;
	std::string stringTop;
	std::string oneGrammar;
	std::string right;

	bool sucess = true;

	std::vector<std::vector<std::string>> allStep;
	std::vector<std::string> oneStep;
	std::string  analysisStackList;
	std::string  stringStackList;

	while (!(analysisStack.top() == "#" && stringStack.top() == "#") || step >= 100)
	{
    
    
		step++;
		oneStep.clear();

		oneStep.push_back(std::to_string(step));
		analysisStackList = GetAnalysisByStack(analysisStack);
		stringStackList = GetStringByStack(stringStack);
		oneStep.push_back(analysisStackList);
		oneStep.push_back(stringStackList);
		analysisTop = analysisStack.top();
		stringTop = stringStack.top();
		if (analysisTop == stringTop)
		{
    
    
			oneStep.push_back("");
			allStep.push_back(oneStep);
			analysisStack.pop();
			stringStack.pop();
			continue;
		}
		oneGrammar = GetGrammar(analysisTop, stringTop, analysisTable);

		oneStep.push_back(oneGrammar);
		allStep.push_back(oneStep);
		if (oneGrammar == "")
		{
    
    
			sucess = false;
			break;
		}
		right = GetRight(oneGrammar);
		analysisStack.pop();
		if (right != "$")
		{
    
    
			MyPush(analysisStack, right);
		}
	}

	std::vector<std::string> successStep = {
    
     std::to_string(++step), "#", "#", "SUCCESS" };
	std::vector<std::string> failStep = {
    
     std::to_string(++step), "?", "?", "FAIL" };

	allStep.push_back(sucess ? successStep : failStep);
	//std::cout << "Success" << std::endl;
	return 	allStep;


}

std::vector<std::vector<std::string>> StringAnalysis(std::string string0,
	std::string startChar, std::map<std::string, std::map<std::string,
	std::string>> analysisTable)
{
    
    

	std::stack<std::string> analysisStack;
	std::stack<std::string> stringStack;


	InitAnalysisStack(analysisStack, startChar);
	InitStringStack(stringStack, string0);

	//PrintStack(stringStack);
	//std::cout << std::endl;
	//PrintStack(analysisStack);

	int step = 0;

	std::vector<std::vector<std::string>> allStep = Func(analysisStack, stringStack, analysisTable, step);

	return allStep;
}

// *************************************************************************************************



void GetOneLeft_Right2(const std::string oneGrammer, std::map<std::string, std::set<std::string>>& left_Right)
{
    
    
	std::string word = "";
	word = oneGrammer.substr(0, 1);

	int i = 4;

	if (oneGrammer.substr(1, 1) == "'")
	{
    
    
		i++;
		word += oneGrammer.substr(1, 1);
	}

	std::string key = word;

	word = "";

	for (; i < oneGrammer.length(); i++)
	{
    
    
		if (oneGrammer[i] == '|')
		{
    
    
			left_Right[key].insert(word);
			word = "";
			continue;
		}
		word += oneGrammer[i];
	}
	left_Right[key].insert(word);
}



void GetAllRightMap(std::map<std::string, std::set<std::string>>& left_Right, const std::vector<std::string> grammarList)
{
    
    
	for (std::string oneGrammar : grammarList)
	{
    
    
		GetOneLeft_Right2(oneGrammar, left_Right);
	}
}

void PrintLeft_Right2(std::map<std::string, std::set<std::string>>& left_Right)
{
    
    
	for (auto item : left_Right)
	{
    
    
		std::cout << item.first << ": {";
		for (auto ii : item.second)
		{
    
    
			std::cout << ii << ", ";
		}
		std::cout << "\b\b}" << std::endl;
	}
}

// 判断是否是终结符号
bool IsTerminator(std::string ch, const std::vector<std::string>& terminator)
{
    
    
	for (std::string item : terminator)
	{
    
    
		if (ch == item)
		{
    
    
			return true;
		}
	}
	return false;
}

// 判断是否是非终结符号
bool IsNonterminal(std::string ch, const std::vector<std::string>& nonterminal)
{
    
    
	for (std::string item : nonterminal)
	{
    
    
		if (ch == item)
		{
    
    
			return true;
		}
	}
	return false;
}

void PrintTerminator(const std::vector<std::string>& terminatorList)
{
    
    
	std::cout << "终结符号集 = { ";
	for (std::string item : terminatorList)
	{
    
    
		std::cout << item << ", ";
	}
	std::cout << "\b\b";
	std::cout << " }" << std::endl;
}


void PrintNonterminal(const std::vector<std::string>& nonterminalList)
{
    
    
	std::cout << "非终结符号集 = { ";
	for (std::string item : nonterminalList)
	{
    
    
		std::cout << item << ", ";
	}
	std::cout << "\b\b";
	std::cout << " }" << std::endl << std::endl;
}

// 将去重的 set 集合 赋值给 vector 集合
void SetToVector(std::vector<std::string>& v, const std::set<std::string>& s)
{
    
    
	v.clear();
	for (std::string item : s)
	{
    
    
		v.push_back(item);
	}
}

// 求解终结符号集 和 非终结符号集
void GetTerminator_Nonterminal(const std::vector<std::string>& grammarList, std::vector<std::string>& terminatorList, std::vector<std::string>& nonterminalList)
{
    
    
	std::set<std::string> terminator;
	std::set<std::string> nonterminal;
	for (std::string oneGrammar : grammarList)
	{
    
    
		int len = oneGrammar.length();
		for (int i = 0; i < len; i++)
		{
    
    
			if (oneGrammar[i] == '|')
			{
    
    
				continue;
			}
			else if (i < len - 1 && oneGrammar[i] == '-' && oneGrammar[i + 1] == '>')
			{
    
    
				i++;
				continue;
			}
			else if (i < len - 2 && oneGrammar[i] == ':' && oneGrammar[i + 1] == ':' && oneGrammar[i + 2] == '=')
			{
    
    
				i += 2;
				continue;
			}
			else if (oneGrammar[i] >= 'A' && oneGrammar[i] <= 'Z')
			{
    
    
				if (i < len - 1 && oneGrammar[i + 1] == '\'')
				{
    
    
					nonterminal.insert(oneGrammar.substr(i, 1) + "'");
					i++;
				}
				else
				{
    
    
					nonterminal.insert(oneGrammar.substr(i, 1));
				}
			}
			else
			{
    
    
				terminator.insert(oneGrammar.substr(i, 1));
			}
		}
	}
	SetToVector(nonterminalList, nonterminal);
	SetToVector(terminatorList, terminator);
}


// *************************************************************************************************




int main()
{
    
    
	std::vector<std::string> grammarList;
	std::vector<std::string> allSentence;
	std::vector<std::string> terminatorList;
	std::vector<std::string> nonterminalList;
	std::vector<std::string> allLeftList;
	std::vector<std::string> allRightList;
	std::vector<std::string> allSentenceList;
	std::map<std::string, std::map<std::string, std::string>> analysisTable;
	std::vector<std::vector<std::string>> allStep;
	std::map<std::string, std::set<std::string>> allRightMap;
	std::map<std::string, std::set<std::string>> Follow;
	std::map<std::string, std::set<std::string>> First;
	std::string string0;
	std::string startChar;

	ReadGrammerFile(grammarList, "code.txt");
	std::cout << "原始文法如下" << std::endl;
	PrintGrammerList(grammarList);

	// **1 消除左递归
	EliminateLeftRecursion(grammarList);

	std::cout << "消除左递归文法如下" << std::endl;
	PrintGrammerList(grammarList);

	GetTerminator_Nonterminal(grammarList, terminatorList, nonterminalList);

	PrintTerminator(terminatorList);
	PrintNonterminal(nonterminalList);

	GetAllRightMap(allRightMap, grammarList);

	

	// 求解全部右部
	allRightList = GetGrammarAllRight(allRightMap, nonterminalList);
	// 求解全部左部
	allLeftList = nonterminalList;

	PrintAllSentence(allRightList);

	// 获取所有的产生式,即将有多个侯选式的产生式分割为独立的产生式
	GetAllSentence(allSentence, allLeftList, allRightList);

	// **2 求解 First 集合
	First = GetFirstSet(allSentence, grammarList, terminatorList, nonterminalList);
	PrintFirst22(First);

	// **3 求解 Follow 集合
	Follow = GetFollowSet(grammarList);
	PrintFollow(Follow);


	// **4 构造分析表
	analysisTable = AnalysisTableConstructor(First, Follow, terminatorList, nonterminalList, allRightMap);
	PrintAnalysisTable(analysisTable, terminatorList, nonterminalList);

	string0 = "i+i*i";
	startChar = GetFirstChar2(grammarList[0]);

	// **5 符号串分析
	allStep = StringAnalysis(string0, startChar, analysisTable);

	// **6 打印符号串分析步骤
	PrintAllStep(allStep, string0);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35500719/article/details/128258235