文章目录
- 一、文法
- 二、源代码模块
- (一)消除文法的左递归
- (二)求First集
- (三)求Follow集
- (四)构建LL(1)分析表
- (五)符号串分析
- (六)主函数
- 三、实验结果
- 四、视频讲解
- 五、全部源代码
一、文法
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站详细讲解