1 运行结果
(1)测试文法一(输入文件产生式右部与句子全部以单个空格隔开,测试文法必须是LL(1)的):
E->T E’
E’->+ T E’
E’->#
T->F T’
T’->* F T’
T’->#
F->i
F->( E )
测试句子:i + i * i
测试结果如下图所示(由于图太大,分割成几部分展示)。
(2)测试文法二:
E->T E’
E’->+ E
E’->#
T->F T’
T’->T
T’->#
F->P F’
F’->* F’
F’->#
P->( E )
P->a
P->b
P->^
测试句子:( a ^ b + a ) * b
以下是分析过程与结果输出到文件的测试。经测试,程序运行的过程和结果(包含计算First集Follow集Select集、构造预测分析表分析表、分析过程等)能正常输出到文件里。
2 项目代码
只有一个文件main.cpp:
#include<cstdio>
#include<map>
#include<iostream>
#include<fstream>
#include<iomanip>
#include<vector>
#include<set>
#include<string>
using namespace std;
const int wordnumPerLine = 7;
bool writeFile = false;
FILE* grammerFile;
char fname[50],outfname[50],c,reply[50];
string analyzedString;
#define readLine if( fscanf(grammerFile,"%[^\n]%c",theLine,&c)==EOF) return;
#pragma region 工具函数
inline bool isInVector(vector<string> vec,string val) {
vector<string>::iterator iter = find(vec.begin(), vec.end(), val);
if (iter == vec.end())
return false;
return true;
}
inline set<string> getNoneEmptySet(set<string> s) {
//得到无空集
set<string> ans = s;
set<string>::iterator it = ans.find("#");
if (it!= ans.end()) {
ans.erase(it);
}
return ans;
}
inline bool isNoneTerminal(string x) {
return x.length() > 0 && x[0] >= 'A'&&x[0] <= 'Z';
}
inline vector<string> splitString(string oriString, char splitChar = ' ') {
vector<string> vec;
oriString += ' ';
int splitpos;
while (splitpos = oriString.find(splitChar)!=string::npos) {
vec.push_back(oriString.substr(0, splitpos));
oriString = oriString.substr(splitpos+1);
}
return vec;
}
inline string vectorToString(vector<string> vec,bool reverse = false) {
string ansStr = "";
if (reverse) {
for (int i = vec.size()-1; i >=0; i--) {
ansStr += vec[i] + " ";
}
}
else {
for (int i = 0; i < vec.size(); i++) {
ansStr += vec[i] + " ";
}
}
return ansStr;
}
#pragma endregion
struct Production{
string left;
vector<string>right;
bool isEmpty = false;
string getRight() {
string ans = "";
for (int i = 0; i < right.size() - 1; i++)
ans += right[i] + " ";
if (!right.empty()) {
ans += right.back();
}
return ans;
}
string getProduction() {
return left + "->" + getRight();
}
};
struct Grammer
{
vector<Production> productions;//文法产生式
vector<string> nonTerminal;//文法非终结符
vector<string> terminal;//文法终结符
map<string,set<string> > firstSet;//first集
map<string,set<string> > followSet;//follow集
vector<set<string> > select;//第i条产生式的select集
map<string, bool> canReachEmpty;//非终结符表
string startSymbol= "";//开始符号
map<pair<string, string>, int> predictionMap;//非终结符A遇到终结符b时,使用第i条产生式
friend ostream & operator <<(ostream & os, const Grammer & g);
}grammer;
struct Description
{
string analyzeStr;
string remainStr;
string matchStr;
Description() {
}
Description(string analyzeStr, string remainStr) {
this->analyzeStr = analyzeStr;
this->remainStr = remainStr;
}
};
struct Sentence
{
vector<string> analyzeStack;
vector<string> remainString;
vector<Description > description;
string sentenceContent;
void analyzeString() {
//分析串
int productionIndex;
string nAnaStr, nRemStr;
vector<string> nRight;
analyzeStack.clear();//原有分析栈清空
description.clear();//原有描述清空
remainString = splitString(sentenceContent + " #");//获取剩余输入串(默认以空格隔开)
analyzeStack.push_back("#");//压入#
analyzeStack.push_back(grammer.startSymbol);//压入开始符号
while (true) {
nAnaStr