南京邮电大学编译原理实验二(语法分析程序)

一、文法

E::=E+T|T
T::=T*F|F
F::=(E)|i

二、源代码模块

(一)消除文法的左递归

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

// 1读取文法
void ReadGrammarFile(std::vector<std::string>& grammarList, std::string url)
{
    
    
	std::ifstream input(url);
	std::string line;

	if (input)
	{
    
    
		while (std::getline(input, line))
		{
    
    
			grammarList.push_back(line);
		}
	}
}

// 打印文法
void PrintGrammar(const std::vector<std::string>& grammarList)
{
    
    
	for (std::string oneGrammar : grammarList)
	{
    
    
		std::cout << oneGrammar << std::endl;
	}
}

void SetToVector(const std::set<std::string>& oneSet, std::vector<std::string>& oneVector)
{
    
    
	oneVector.clear();
	for (std::string item : oneSet)
	{
    
    
		oneVector.push_back(item);
	}
}

// 3求解终结符号集 和 非终结符号集
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(nonterminal, nonterminalList);
	SetToVector(terminator, terminatorList);
}

// 打印终结符号
void PrintTerminator(const std::vector<std::string>& terminatorList)
{
    
    
	std::cout << "终结符号集为" << std::endl;
	for (std::string item : terminatorList)
	{
    
    
		std::cout << item << " ";
	}
	std::cout << std::endl;
}

// 打印非终结符号
void PrintNonterminal(const std::vector<std::string>& nonterminalList)
{
    
    
	std::cout << "非终结符号集为" << std::endl;
	for (std::string item : nonterminalList)
	{
    
    
		std::cout << item << " ";
	}
	std::cout << std::endl;
}

std::string GetFirstChar(const std::string str)
{
    
    
	std::string firstChar = str.substr(0, 1);
	if (str.length() > 1 && str.substr(1, 1) == "'")
	{
    
    
		firstChar = str.substr(0, 2);
	}
	return firstChar;
}

// 分割一条文法
std::vector<std::string> DivideOneGrammar(const std::string oneGrammar)
{
    
    
	std::vector<std::string> oneDividedGrammar;

	std::string part;
	int i = 1;
	part = oneGrammar.substr(0, 1);

	char startChar = oneGrammar[0];

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

	oneDividedGrammar.push_back(part);

	if (oneGrammar.substr(i, 2) == "->")
	{
    
    
		oneDividedGrammar.push_back("->");
		part = "";
		i += 2;
	}
	else if (oneGrammar.substr(i, 3) == "::=")
	{
    
    
		oneDividedGrammar.push_back("::=");
		part = "";
		i += 3;
	}
	else
	{
    
    
		std::cout << "文法错误" << std::endl;
		exit(-1);
	}

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

	oneDividedGrammar.push_back(part);
	return oneDividedGrammar;
}

// 获取一条产生式的全部侯选式
void GetOneGrammarAllRight(const std::string oneGrammar, std::map<std::string, std::vector<std::string>>& allRightMap)
{
    
    
	std::vector<std::string> oneDividedGrammar = DivideOneGrammar(oneGrammar);

	std::string key = oneDividedGrammar[0];

	for (int i = 2; i < oneDividedGrammar.size(); i++)
	{
    
    
		std::string part = oneDividedGrammar[i];
		if (part != "|")
		{
    
    
			allRightMap[key].push_back(part);
		}
	}
}

// 获取全部产生式的全部侯选式
void GetAllRightMap(std::map<std::string, std::vector<std::string>>& allRightMap,
	const std::vector<std::string>& grammarList)
{
    
    
	for (std::string oneGrammar : grammarList)
	{
    
    
		GetOneGrammarAllRight(oneGrammar, allRightMap);
	}
}

// 通过左部求当前产生式在文法当中是第几条产生式
int GetGrammarIndexByLeft(std::string left, const std::vector<std::string>& grammarList)
{
    
    
	for (int i = 0; i < grammarList.size(); i++)
	{
    
    
		std::string oneGrammar = grammarList[i];
		std::string firstChar = GetFirstChar(oneGrammar);

		if (firstChar == left)
		{
    
    
			return i;
		}
	}
}

// 获取产生左递归的索引对,即产生左递归的位置
std::vector<std::pair<std::string, int>> GetPairIndex(const std::vector<std::string>& nonterminalList,
	std::map<std::string, std::vector<std::string>> allRightMap)
{
    
    
	std::vector<std::pair<std::string, int>> leftRecursionIndex;
	for (std::string left : nonterminalList)
	{
    
    
		std::vector<std::string> oneAllRight = allRightMap[left];
		// 遍历每一条侯选式
		for (int i = 0; i < oneAllRight.size(); i++)
		{
    
    
			std::string oneRight = oneAllRight[i];
			std::string startChar = GetFirstChar(oneRight);
			if (left == startChar)
			{
    
    
				leftRecursionIndex.push_back(std::make_pair(left, i));
			}
		}
	}
	return leftRecursionIndex;
}


// 消除一条产生式的左递归
void EliminateOneLeftRecursion(std::string left, int rightIndex, std::vector<std::string>& grammarList,
	const std::vector<std::string>& oneAllRight, int grammarIndex)
{
    
    
	std::string A = left;
	std::string alpha = oneAllRight[rightIndex].substr(A.length());
	std::string beta = oneAllRight[1 - rightIndex];

	grammarList.erase(grammarList.begin() + grammarIndex);

	std::string grammar1 = A + "::=" + beta + A + "'";
	std::string grammar2 = A + "'::=" + alpha +  A + "'|$";

	grammarList.push_back(grammar1);
	grammarList.push_back(grammar2);
}

// 消除全部产生式的左递归
void EliminateAllLeftRecursion(const std::vector<std::string>& nonterminalList, 
	std::vector<std::string>& grammarList,
	std::map<std::string, std::vector<std::string>> allRightMap)
{
    
    
	 // 索引对 <左部,第几个侯选式>
	std::vector<std::pair<std::string, int>> pairIndex = GetPairIndex(nonterminalList, allRightMap);

	for (int i = 0; i < pairIndex.size(); i++)
	{
    
    
		std::string left = pairIndex[i].first;
		int rightIndex = pairIndex[i].second;
		std::vector<std::string> oneAllRight = allRightMap[left];
		// 获取当前的产生式是文法的第几条产生式
		int grammarIndex = GetGrammarIndexByLeft(left, grammarList);

		EliminateOneLeftRecursion(left, rightIndex, grammarList, oneAllRight, grammarIndex);
	}
}

// 设置新文法的第一条产生式
void SetFirstGrammar(std::vector<std::string>& grammarList, std::string startChar)
{
    
    
	std::string oneGrammar = grammarList[0];
	std::string firstChar = GetFirstChar(oneGrammar);

	if (firstChar == startChar)
	{
    
    
		return;
	}

	for (int i = 1; i < grammarList.size(); i++)
	{
    
    
		oneGrammar = grammarList[i];
		firstChar = GetFirstChar(oneGrammar);
		if (startChar == firstChar)
		{
    
    
			grammarList[i] = grammarList[0];
			grammarList[0] = oneGrammar;
			break;
		}
	}
}

// 消除左递归的主方法
void EliminateLeftRecursion(const std::vector<std::string>& nonterminalList, std::vector<std::string>& grammarList)
{
    
    
	// 1 求所有产生式的全部侯选式
	std::map<std::string, std::vector<std::string>> allRightMap;

	GetAllRightMap(allRightMap, grammarList);

	// 文法的开始符号
	const std::string grammarStartChar = GetFirstChar(grammarList[0]);

	EliminateAllLeftRecursion(nonterminalList, grammarList, allRightMap);

	SetFirstGrammar(grammarList, grammarStartChar);
}

(二)求First集

#pragma once
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#include <fstream>
#include <stack>
#include <string>
#include "EliminateLeftRecursion.h"

// 获取全部文法的全部左部和右部
std::vector<std::string> GetAllLeftRightList(std::map<std::string, std::vector<std::string>> allRightMap)
{
    
    
	std::vector<std::string> allSentenceList;
	std::set<std::string> allSentenceSet;
	for (auto item: allRightMap)
	{
    
    
		
		allSentenceSet.insert(item.first);
		for (auto item2 : item.second)
		{
    
    
			allSentenceSet.insert(item2);
		}
	}
	SetToVector(allSentenceSet, allSentenceList);
	return allSentenceList;
}

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

// 求一条句型的 First 集
void GetOneFirst(std::string& sentence, 
	std::vector<std::string>& First,
	const std::vector<std::string>& terminator,
	std::map<std::string, std::vector<std::string>> allRightMap)
{
    
    
	// 求该句型的开始符号
	std::string firstChar = GetFirstChar(sentence);
	
	// 如果是终结符号,那么 firstChar 就是当前句型 First集 的唯一元素,直接返回
	if (IsTerminator(firstChar, terminator))
	{
    
    
		First.push_back(firstChar);
		return;
	}
	// 如果是非终结符号
	else
	{
    
    
		// 根据首字符确定 产生式
		std::vector<std::string> oneAllRight = allRightMap[firstChar];
		// 遍历每一条产生式
		for (std::string item : oneAllRight)
		{
    
    
			// 新句型 = 用产生式替换原句型的首字符 
			sentence = item + sentence.substr(firstChar.length());
			// 再次递归,直到遇到终结符号,自动结束递归
			GetOneFirst(sentence, First, terminator, allRightMap);
		}
	}
}


// 打印全部的左部和右部的各个侯选式
void PrintAllSentence(const std::vector<std::string>& allSentence)
{
    
    
	std::cout << "全部的左部和右部如下" << std::endl;
	for (std::string item : allSentence)
	{
    
    
		std::cout << item << "  " << std::endl;
	}
	std::cout << std::endl;
}


// 打印 First集
void PrintFirst(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 << std::left << std::setw(4) << item.first << ": { ";
		for (std::string ii : item.second)
		{
    
    
			std::cout << ii << ", ";
		}
		std::cout << "\b\b }" << std::endl;
	}
	std::cout << std::endl;
}

// 1求 First集 主函数
std::map<std::string, std::set<std::string>> GetFirstSet(
	const std::vector<std::string>& terminatorList,
	const std::vector<std::string>& nonterminalList,
	std::map<std::string, std::vector<std::string>> allRightMap)
{
    
    
	// 所有产生式的左部和右部的全部侯选式
	std::vector<std::string> allSentenceList;

	allSentenceList = GetAllLeftRightList(allRightMap);
		
	PrintAllSentence(allSentenceList);


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

	// 一个句型的 First 集
	std::vector<std::string> oneFirst;

	for (std::string sentence : allSentenceList)
	{
    
    
		std::string sentenceTemp = sentence;
		oneFirst.clear();
		GetOneFirst(sentence, oneFirst, terminatorList, allRightMap);
		for (std::string item : oneFirst)
		{
    
    
			First[sentenceTemp].insert(item);
		}
	}
	return First;
}

(三)求Follow集

#pragma once
#include "EliminateLeftRecursion.h"
#include "MyFirst.h"

// PairSet 转换为 PairVector
void PairSetToPairVector(const std::set<std::pair<std::string, std::string>>& onePairSet, 
	std::vector<std::pair<std::string, std::string>>& onePairVector)
{
    
    
	onePairVector.clear();
	for (std::pair<std::string, std::string> item : onePairSet)
	{
    
    
		onePairVector.push_back(item);
	}
}

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

// 输入侯选式返回所有可能的产生式的左部 
std::vector<std::string> GetOneCandidateAllLeft(const std::string candidate,
	const std::map<std::string, std::vector<std::string>> allRightMap)
{
    
    
	std::vector<std::string> allLeft;

	for (std::pair<std::string, std::vector<std::string>> item : allRightMap)
	{
    
    
		std::string left = item.first;
		std::vector<std::string> oneAllRight = item.second;
		for (std::string oneRight : oneAllRight)
		{
    
    
			if (oneRight == candidate)
			{
    
    
				allLeft.push_back(left);
				break;
			}
		}
	}
	return allLeft;
}


// 获取全部文法的全部右部
std::vector<std::string> GetAllRightList(std::map<std::string, std::vector<std::string>> allRightMap, 
	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 : allRightMap[key])
		{
    
    
			allRightSet.insert(item);
		}
	}
	SetToVector(allRightSet, allRightList);
	return allRightList;
}

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

// 寻找一条侯选式的 B 和 Beta             A::=αBβ
std::vector<std::pair<std::string, std::string>> FindOneCandidateBBeta(
	std::string oneCandidate,
	const std::vector<std::string>& nonterminalList, 
	const std::vector<std::string>& oneCandidateCharList)
{
    
    
	std::vector<std::pair<std::string, std::string>> oneBBeta;
	int index = 0;
	int charNum = oneCandidateCharList.size();
	std::string beta;
	std::string oneChar;

	// E::=aEFcd
	// B = E
	// B = F

	for (int i = 0; i < charNum; i++)
	{
    
    
		oneChar = oneCandidateCharList[i];
		index += oneChar.length();
		// 如果是非终结符号
		if (IsNonterminal(oneChar, nonterminalList))
		{
    
    
			std::string B = oneChar;
			beta = oneCandidate.substr(index);
			beta = beta == "" ? "$" : beta;
			oneBBeta.push_back(make_pair(B, beta));
		}
	}
	return oneBBeta;
}

// 寻找全部侯选式的 B 和 Beta
std::vector<std::pair<std::string, std::string>> FindAllCandidateBBeta(
	const std::vector<std::string>& allCandidateList,
	const std::vector<std::string>& nonterminalList)
{
    
    
	std::vector<std::pair<std::string, std::string>> allBBetaList;
	std::set<std::pair<std::string, std::string>> allBBetaSet;
	std::vector<std::string> oneCandidateAllCharList;
	std::vector<std::pair<std::string, std::string>> oneCandidateBBetaList;
	for (std::string oneCandidate : allCandidateList)
	{
    
    
		oneCandidateAllCharList = GetOneCandidateAllCharacter(oneCandidate);
		oneCandidateBBetaList = FindOneCandidateBBeta(oneCandidate, nonterminalList, oneCandidateAllCharList);
		for (std::pair<std::string, std::string> oneBBeta : oneCandidateBBetaList)
		{
    
    
			allBBetaSet.insert(oneBBeta);
		}
	}
	PairSetToPairVector(allBBetaSet, allBBetaList);
	return allBBetaList;
}

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

// 求解 FOLLOW 集合 规则二
void Rule2(std::map<std::string, std::set<std::string>>& Follow,
	const std::vector<std::pair<std::string, std::string>> allBBetaList, 
	const std::vector<std::string>& terminatorList, 
	std::map<std::string, std::vector<std::string>> allRightMap)
{
    
    
	std::vector<std::string> FirstSetOfBeta;
	for (std::pair<std::string, std::string> oneBBeta : allBBetaList)
	{
    
    
		FirstSetOfBeta.clear();
		std::string B = oneBBeta.first;
		std::string beta = oneBBeta.second;

		GetOneFirst(beta, FirstSetOfBeta, terminatorList, allRightMap);
		for (std::string item : FirstSetOfBeta)
		{
    
    
			if (item != "$")
			{
    
    
				Follow[B].insert(item);
			}
		}
	}
}


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

	std::string firstChar = GetFirstChar(beta);

	if (IsTerminator(firstChar, terminatorList))
	{
    
    
		if (firstChar == "$")
		{
    
    
			flag = true;
			ASet.insert(lastA);
		}
	}
	else
	{
    
    
		for (std::string right : allRightMap[firstChar])
		{
    
    
			std::string newBeta = right + beta.substr(firstChar.size());
			oneBBeta.second = newBeta;
			lastA = firstChar;
			IsGeneralizedDerivation(lastA, oneBBeta, allRightMap, terminatorList, flag, ASet);
		}
	}
}

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

// 求解 FOLLOW 集合 规则三
void Rule3(std::map<std::string, std::set<std::string>>& Follow,
	const std::vector<std::string>& allRightList,
	const std::map<std::string, std::vector<std::string>> allRightMap,
	const std::vector<std::string>& terminatorList,
	const std::vector<std::string>& nonterminalList)
{
    
    
	// 先保存一份 Follow集
	std::map<std::string, std::set<std::string>> tempFollow = Follow;
	std::vector<std::string> allChar;
	std::vector<std::pair<std::string, std::string>> oneCandidateBBetaList;
	std::vector<std::string> oneCandidateAllLeft;
	bool flag;
	for (std::string oneCandidate : allRightList)
	{
    
    
		allChar = GetOneCandidateAllCharacter(oneCandidate);
		oneCandidateBBetaList = FindOneCandidateBBeta(oneCandidate, nonterminalList, allChar);
		oneCandidateAllLeft = GetOneCandidateAllLeft(oneCandidate, allRightMap);
		for (std::pair<std::string, std::string> oneBBeta : oneCandidateBBetaList)
		{
    
    
			for (std::string left : oneCandidateAllLeft)
			{
    
    
				std::set<std::string> ASet;
				flag = false;
				std::string B = oneBBeta.first;
				std::string beta = oneBBeta.second;
				IsGeneralizedDerivation(left, oneBBeta, allRightMap, terminatorList, flag, ASet);
				// 如果能广义推导出 $, 则 FOLLOW(A) 中全部终结符均属于FOLLOW(B)
				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, nonterminalList))
	{
    
    
		Rule3(Follow, allRightList, allRightMap, terminatorList, nonterminalList);
	}
}

// 打印 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 << std::left << std::setw(3) << item.first << " : { ";
		for (std::string ii : item.second)
		{
    
    
			std::cout << ii << ", ";
		}
		std::cout << "\b\b }" << std::endl;
	}
	std::cout << std::endl;
	return 0;
}

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

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

	std::vector<std::string> allCandidateList = GetAllLeftRightList(allRightMap);

	allBBeta = FindAllCandidateBBeta(allCandidateList, nonterminalList);

	Rule1(Follow, grammarStartChar);
	std::cout << "规则一" << std::endl;
	PrintFollow(Follow);

	Rule2(Follow, allBBeta, terminatorList, allRightMap);
	std::cout << "规则二" << std::endl;
	PrintFollow(Follow);

	Rule3(Follow, allCandidateList, allRightMap, terminatorList, nonterminalList);
	std::cout << "规则三" << std::endl;

	return Follow;
}


(四)构建LL(1)分析表

#pragma once
#include "MyFirst.h"
#include "MyFollow.h"

// 输入非空侯选式,返回左部
std::string GetSartCharByCandidate(std::string candidate, std::map<std::string, std::vector<std::string>> allRightMap)
{
    
    
	std::string left;
	for (std::pair<std::string, std::vector<std::string>> oneLeftAllRight : allRightMap)
	{
    
    
		left = oneLeftAllRight.first;
		for (std::string oneCandidate : oneLeftAllRight.second)
		{
    
    
			// 如果此产生式存在侯选式与目标侯选式相匹配,就返回此产生式的左部
			if (oneCandidate == candidate)
			{
    
    
				return left;
			}
		}
	}
	std::cout << "出错了" << std::endl;
	return "Error";
}

// 打印 LL1 分析表
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,
	const std::map<std::string, std::set<std::string>>& First,
	const std::map<std::string, std::vector<std::string>>& allRightMap,
	const std::vector<std::string>& nonterminalList)
{
    
    																					   
	// 遍历每一个句型的 First集
	for (std::pair<std::string, std::set<std::string>> onefirstSet : First)
	{
    
    
		// 一个句型
		std::string oneSentence = onefirstSet.first;
		// 如果该句型是非终结符号 或者 空符号,因为分析表的第一行是终结符号
		if (IsNonterminal(oneSentence, nonterminalList) || oneSentence == "$")
		{
    
    
			continue;
		}
		// 句型是终结符号
		for (std::string item : onefirstSet.second)
		{
    
    
			std::string left = GetSartCharByCandidate(oneSentence, allRightMap);
			std::string i = left;
			std::string j = item;
			std::string grammar = left + "->" + oneSentence;
			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,
	const std::map<std::string, std::vector<std::string>>& allRightMap,
	const std::vector<std::string>& nonterminalList)
{
    
    

	for (std::pair<std::string, std::vector<std::string>> oneLeftAllRight : allRightMap)
	{
    
    
		std::string left = oneLeftAllRight.first;
		std::vector<std::string> oneAllRight = oneLeftAllRight.second;
		for (std::string oneCandidate : oneAllRight)
		{
    
    
			if (oneCandidate == "$")
			{
    
    
				std::string i = left;
				auto COL = Follow[left];
				for (std::string j : COL)
				{
    
    
					std::string grammar = left + "->$";
					analysisTable[i][j] = grammar;
				}
			}
		}
	}
}

// 初始化 LL(1) 分析表
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] = "";
		}
	}
}


// 构建 LL(1) 分析表主函数
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::vector<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;
		}
	}

	InitAnalysisTable(analysisTable, ROW, COL);

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

	return analysisTable;
}

(五)符号串分析

#pragma once
#include "AnalysisTable.h"


//************************符号串分析函数定义**********************************************************

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 = GetFirstChar(oneGrammar);
	std::string right;
	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);

	int step = 0;

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

	return allStep;
}

(六)主函数

#include "EliminateLeftRecursion.h"
#include "MyFirst.h"
#include "MyFollow.h"
#include "AnalysisTable.h"
#include "StringAnalysis.h"

int main()
{
    
    
	std::vector<std::string> grammarList;
	std::vector<std::string> terminatorList;
	std::vector<std::string> nonterminalList;

	ReadGrammerFile(grammarList, "code.txt");

	std::cout << "原始文法如下" << std::endl;
	PrintGrammerList(grammarList);

	GetTerminator_Nonterminal(grammarList, terminatorList, nonterminalList);

	EliminateLeftRecursion(nonterminalList, grammarList);

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

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


	std::map<std::string, std::set<std::string>> First;
	std::map<std::string, std::vector<std::string>> allRightMap;

	GetTerminator_Nonterminal(grammarList, terminatorList, nonterminalList);

	//PrintTerminator(terminatorList);

	GetAllRightMap(allRightMap, grammarList);

	

	// **2 求解全部左部和右部的 First 集合
	First = GetFirstSet(terminatorList, nonterminalList, allRightMap);
	PrintFirst(First);

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

	std::string grammarStartChar = GetFirstChar(grammarList[0]);

	std::map<std::string, std::set<std::string>> Follow;
	Follow = GetFollowSet(terminatorList, nonterminalList, allRightMap, grammarStartChar);
	PrintFollow(Follow);

	// *************************************************************************
	std::map<std::string, std::map<std::string, std::string>> analysisTable;
	analysisTable = AnalysisTableConstructor(First, Follow, terminatorList, nonterminalList, allRightMap);
	PrintAnalysisTable(analysisTable, terminatorList, nonterminalList);

	std::string string0 = "i+i*i";

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

	PrintAllStep(allStep, string0);

	return 0;
}

三、实验结果

原始文法如下
E::=E+T|T
T::=T*F|F
F::=(E)|i

消除左递归文法如下
E::=TE'
F::=(E)|i
E'::=+TE'|$
T::=FT'
T'::=*FT'|$

FIRST 集如下
$: {
    
    $}
(E): {
    
    (}
*FT': {
    
    *}
+TE': {
    
    +}
E: {
    
    (, i}
E': {
    
    $, +}
F: {
    
    (, i}
FT': {
    
    (, i}
T: {
    
    (, i}
T': {
    
    $, *}
TE': {
    
    (, i}
i: {
    
    i}

规则一
FOLLOW 集如下
E: {
    
    #}

规则二
FOLLOW 集如下
E: {
    
    #, )}
F: {
    
    *}
T: {
    
    +}

规则三
FOLLOW 集如下
E: {
    
    #, )}
E': {
    
    #, )}
F: {
    
    #, ), *, +}
T: {
    
    #, ), +}
T': {
    
    #, ), +}

LL(1) 分析表如下
     |      i         +         *         )         (         #
----------------------------------------------------------------------
E    |    E->TE'                                  E->TE'
E'   |              E'->+TE'            E'->$               E'->$
F    |    F->i                                    F->(E)
T    |    T->FT'                                  T->FT'
T'   |              T'->$     T'->*FT'  T'->$               T'->$

符号串 i+i*i 的分析过程
1     #E            i+i*i#     E->TE'
2     #E'T          i+i*i#     T->FT'
3     #E'T'F        i+i*i#     F->i
4     #E'T'i        i+i*i#
5     #E'T'          +i*i#     T'->$
6     #E'            +i*i#     E'->+TE'
7     #E'T+          +i*i#
8     #E'T            i*i#     T->FT'
9     #E'T'F          i*i#     F->i
10    #E'T'i          i*i#
11    #E'T'            *i#     T'->*FT'
12    #E'T'F*          *i#
13    #E'T'F            i#     F->i
14    #E'T'i            i#
15    #E'T'              #     T'->$
16    #E'                #     E'->$
17    #                  #     SUCCESS

在这里插入图片描述

四、视频讲解

B站详细讲解
在这里插入图片描述

五、全部源代码

点我查看全部源代码

猜你喜欢

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