编译原理 LL(1)文法分析程序详解
在开始LL(1)文法分析之前,先要明白几个概念——first集、follow集、select集,下面分别介绍一下。
First集
设G=(Vt,Vn,P,S)是上下文无关文法。
First(α)={a | α⇒aβ,a∈Vt,a,β∈
V
∗
V^*
V∗},若α⇒
ϵ
\epsilon
ϵ,规定
ϵ
\epsilon
ϵ∈First(α)。称First(α)为α的开始符号集或首符号集。
注意:α⇒aβ和α⇒
ϵ
\epsilon
ϵ中间推导过程可以是间接推导。
Follow集
设G=(Vt,Vn,P,S)是上下文无关文法。
A∈Vn,S是开始符号
Follow(A)={a | S⇒αAβ且a∈Vt,a∈First(β),α∈
V
∗
t
V^*t
V∗t,β∈
V
+
V^+
V+},若S⇒αAβ,且β⇒
ϵ
\epsilon
ϵ,则#∈Follow(A)。
注意:S⇒αAβ和β⇒
ϵ
\epsilon
ϵ中间推导过程可以是间接推导。
Select集
一个产生式的选择符号集Select。给定上下文无法文法的产生式A->α,A∈Vn,α∈
V
∗
V^*
V∗,若α不能直接或者间接推导出
ϵ
\epsilon
ϵ,则
Select(A->α)=First(α)。若α⇒
ϵ
\epsilon
ϵ,则Select(A->α)=First(α)-{
ϵ
\epsilon
ϵ} U Follow(A)。
注意:1. α⇒
ϵ
\epsilon
ϵ中间推导过程可以是间接推导。
LL(1)文法分析程序
文法例子(符合LL(1)文法)
A->TB
B->+TB
B->E
T->FC
C->*FC
C->E
F->i
F->(A)
第一步,求出能推出
ϵ
\epsilon
ϵ的非终结符。
1.首先建立一个以文法的非终结符个数为上界的一维数组,其数组元素为终结符,对应每一个非终结符有一个标记位,用以记录能否推出
ϵ
\epsilon
ϵ。其值有三种情况:“未定”,“是”,“否”。
enum
{
FU,//否
SH,//是
WD //未定
};
//规定E为空字符
vector<char>Vn;//非终结符
vector<char>Vt;//终结符
vector<char>V;//文法所有字符
vector<string>G;//文法
vector<string>G1;//文法副本
map<char, int>isEVn;//非终结符标记数组
//1 输入文法与初始化
string input;
void inputContextRule()
{
while (cin >> input)
{
if (input == "#") break;
G.push_back(input);
G1.push_back(input);
}
int len = G1.size();
for (int i = 0; i < len; i++)
{
for (int j = 0; j < G1[i].size(); j++)
{
//非终结符加入Vn
//将数组对应的每一非终结符的标记为"未定"
if (G1[i][j] >= 'A' && G1[i][j] <= 'Z' && G1[i][j] != 'E') { Vn.push_back(G1[i][j]); isEVn[G1[i][j]] = WD; }
//终结符加入Vt
if ((G1[i][j] > 'Z' || G1[i][j] < 'A')&&G1[i][j]!='|'&&G1[i][j] != '-' && G1[i][j] != '>') Vt.push_back(G1[i][j]);
}
}
//去重
set<int>se(Vt.begin(), Vt.end());
Vt.assign(se.begin(), se.end());
set<int>s(Vn.begin(), Vn.end());
Vn.assign(s.begin(), s.end());
}
2.扫描文法中的产生式。
(1)删除所有右部含有终结符的产生式,若这使得以某一非终结符为左部的所有产生式都被删除,则将数组中对应该非终结符的标记值改为“否”,说明该非终结符不能推出
ϵ
\epsilon
ϵ。
(2)若某一非终结符的某一产生式右部为
ϵ
\epsilon
ϵ,则将数组中对应该非终结符的标志置为“是”,并从文法中删除该非终结符的所有产生式。
void scamFuc()
{
for (int i = 0; i < G1.size(); i++)
{
for (int j = 3; j < G1[i].size(); j++)
{
if ((G1[i][j] > 'Z' || G1[i][j] < 'A') && G1[i][j] != '|')
{
G1[i]="";
break;
}
}
}
int lenVn = Vn.size();
for (int i = 0; i < lenVn; i++)
{
bool isexit = 0;
for (int j = 0; j < G1.size(); j++)
{
if (Vn[i] == G1[j][0]) {
isexit = 1;
break;
}
}
if (!isexit) {
isEVn[Vn[i]] = FU;
}
}
for (int i = 0; i < G1.size(); i++)
{
if (G[i].size() == 4 && G[i][3] == 'E')
{
isEVn[G[i][0]] = SH;
for (int j = 0; j < G1.size(); j++)
{
if (G1[j][0] == G[i][0])
{
G1[j] = "";
}
}
}
}
}
3.扫描产生式右部的每一个符号
(1)若扫描到的非终结符在数组中对应的标记是“是”,则删去该非终结符;若这时产生式右部为空,则将产生式左部的非终结符在数组中对应的标记改为“是”,并且删除以该非终结符位左部的所有产生式。
(2)若扫描到的非终结符在数组中对应的标记是“否”,则删去该产生式;若这使产生式左部非终结符的有关产生式都被删除,则把在数组中该非终结符对应的标记改成“否”。
void scamRight()
{
for (int i = 0; i < G1.size(); i++)
{
for (int j =3; j < G1[i].size(); j++)
{
if (G1[i][j] >= 'A' && G1[i][j] <= 'Z' && G1[i][j] != 'E' && isEVn[G1[i][j]] == SH)
{
char ch1 = G1[i][j];
G1[i][j] = ' ';
string se;
bool isk = 1;
for (int t = j; t < G[i].size(); t++)
{
if (G1[i][j] != ' ')
{
isk = 0;
}
}
if (isk && G1[i][j - 1] == '>')
{
isEVn[G1[i][0]] = SH;
for (int k = 0; k < G1.size(); k++)
{
if (G1[k][0] == ch1)
{
G1[k] = "";
}
}
}
}
if (G1[i][j] >= 'A' && G1[i][j] <= 'Z' && G1[i][j] != 'E' && isEVn[G1[i][j]] == FU)
{
bool isAlldel = 0;
char ch = G1[i][0];
G1[i] = "";
for (int k = 0; k < G1.size(); k++)
{
for (int t = 0; t < G1[k].size(); t++)
{
if (ch == G1[k][0])
{
isAlldel = 1;
break;
}
}
}
if (!isAlldel) {
isEVn[ch] = FU;
}
}
}
}
}
重复3,直到数组中该非终结符对应的特征不在改变。
第二步 计算First集
1.根据First集定义对每一文法符号X∈V,计算First(X)。
(1).若X∈Vt,则First(X)={X}。
(2).若X∈Vn,且有产生式X->a……,a∈Vt,则a∈First(X)。
(3).若X∈Vn,X->
ϵ
\epsilon
ϵ,则
ϵ
\epsilon
ϵ∈First(X)。
int counts;
for (int i =0;i< V.size(); i++)
{
if (0 != (counts = count(Vt.begin(), Vt.end(), V[i])))
{
First[V[i]] += V[i];
}
if (0 != (counts = count(Vn.begin(), Vn.end(), V[i])))
{
for (int j = 0; j < G.size(); j++)
{
if (V[i] == G[j][0]) {
if (G[j][2] == '>' && (G[j][3] > 'Z' || G[j][3] < 'A') && G[j][3] != '|')
{
First[V[i]] += G[j][3];
}
if (G[j][2] == '>' && G[j][3] == 'E')
{
First[V[i]] += "E";
}
}
}
}
}
(4)若X,Y1,Y2,……Yn∈,而有产生式X->Y1,Y2,……,Yi-1,⇒
ϵ
\epsilon
ϵ时(1<=i<=n),则First(Y1)-{
ϵ
\epsilon
ϵ},First(Y2)-{
ϵ
\epsilon
ϵ},……,First(Yi-1)-{
ϵ
\epsilon
ϵ},First(Yi)都包含在First(X)中。
(5)当(4)中所有Yi⇒
ϵ
\epsilon
ϵ时,则First(X)=First(Y1) U First(Y2) U……U First(Yn) U {
ϵ
\epsilon
ϵ}
注意:所有推导都可以时间接推导。
for (int j = 0; j < G.size(); j++)
{
bool isall = 1;
for (int k = 0; k < G[j].size(); k++)
{
if (G[j][k]>= 'A' && G[j][k]<='Z'){}
else if(G[j][k] == '-' || G[j][k] == '>' || G[j][k] == '|' || G[j][k] == '*' || G[j][k] == '(' || G[j][k] == ')'|| G[j][k] == '+'){}
else if (G[j][k] == 'E')
{
isall = 0;
break;
}
else
{
isall = 0;
break;
}
}
if (isall)
{
bool isall1 = 1;
for (int i = 3; i < G[j].size(); i++)
{
if (isEVn[G[j][i]] != SH)
{
isall1 = 0;
break;
}
}
if (isall1)
{
for (int i = 3; i < G[j].size(); i++)
{
First[G[j][0]] += First[G[j][i]];
}
First[G[j][0]] += 'E';
}
else
{
for (int i = 3; i < G[j].size(); i++)
{
if (isEVn[G[j][i]] == SH)
{
First[G[j][i]].erase(remove(First[G[j][i]].begin(), First[G[j][i]].end(), 'E'), First[G[j][i]].end());
First[G[j][0]] += First[G[j][i]];
f First[G[j][i]] += "E";
}
else
{
First[G[j][0]] += First[G[j][i]];
break;
}
}
}
}
}
反复(2)-(5),直到每个符号的First集不再增大为止。
求完单个文法符号的First集,不难求出一个符号串的First集。
若符号串
α
\alpha
α∈
V
∗
V^*
V∗,
α
\alpha
α=X1X2……Xn,当X1不能直接或者间接推导出
ϵ
\epsilon
ϵ,则置First(
α
\alpha
α)=First(X1)。
若对任何j(1<=j<=i-1,2<=i<=n),
ϵ
\epsilon
ϵ∈First(Xj),
ϵ
\epsilon
ϵ不属于First(Xi),则First(
α
\alpha
α)=U (First(Xj)-{
ϵ
\epsilon
ϵ}) U First(Xi)
当对任何j(1<=j<=n),First(Xj)都含有
ϵ
\epsilon
ϵ时,则First(
α
\alpha
α)=U (First(Xj)) U {
ϵ
\epsilon
ϵ}。
void calsMultiFirst()
{
for (int i = 0; i < G.size(); i++)
{
string s;
int k = 3;
while (k<G[i].size())
{
s += G[i][k];
k++;
}
if (isEVn[s[0]] == FU)
{
First1[s] = First[s[0]];
}
bool isall2 = 1;
int saveks;
for (int ks = 0; ks < s.size(); ks++)
{
if (-1 == First[s[ks]].find("E"))
{
isall2 = 0;
saveks = ks;
break;
}
}
if (isall2)
{
for (int m = 0; m < s.size(); m++)
{
First1[s] = First1[s] + First[s[m]];
}
First1[s] = First1[s] + "E";
}
else
{
for (int t = 0; t < saveks; t++)
{
First[s[t]].erase(remove(First[s[t]].begin(), First[s[t]].end(), 'E'), First[s[t]].end());
First1[s] = First1[s] + First[s[t]];
First[s[t]] += "E";
}
First1[s] += First[s[saveks]];
}
}
}
第三步 计算Follow集
1 设S为文法的开始符号,把{#}加入到Follow(S)中。
2 若A->
α
\alpha
αB
β
\beta
β是一个产生式,则把First(
β
\beta
β)的非空元素加入到Follow(B)中。如果
β
\beta
β⇒
ϵ
\epsilon
ϵ,则把Follow(A)也加入到Follow(B)中。
3反复使用2直到每个非终结符的Follow集不在增大。
void initFollow() {
Follow['A'] = "#";
for (int i = 0; i < Vn.size(); i++)
{
if (Vn[i] != 'A')
{
Follow[Vn[i]] = "";
}
}
}
void calFollow()
{
for (int i = 0; i < Vn.size(); i++)
{
for (int j = 0; j < G.size(); j++)
{
if (G[j][0] == Vn[i])
{
for (int k = 3; k < G[j].size(); k++)
{
string s;
if (G[j][k] >= 'A' && G[j][k] <= 'Z'&& G[j][k]!='E')
{
for (int t = k+1; t < G[j].size(); t++)
{
s += G[j][t];
}
bool isa = 1;
for (int n = 0; n < s.size(); n++)
{
if (isEVn[s[n]] == 0)
{
isa = 0;
//break;
}
}
if (s.size() > 1)
{
if (First1[s] != "") {
for (int m = 0; m < First1[s].size(); m++)
{
if (First1[s][m] != 'E') Follow[G[j][k]] += First1[s][m];
}
if (isa)
{
Follow[G[j][k]] += Follow[Vn[i]];
}
//break;
}
}
else
{
if (s.size() == 0)
{
Follow[G[j][k]] += Follow[Vn[i]];
//break;
}
if (First[s[0]] != "")
{
for (int m = 0; m < First[s[0]].size(); m++)
{
if (First[s[0]][m] != 'E') Follow[G[j][k]] += First[s[0]][m];
}
if (isa)
{
Follow[G[j][k]] += Follow[Vn[i]];
}
// break;
}
}
}
}
}
}
}
}
第四步 计算select集,根据select集的定义求。
void calselect()
{
for (int i = 0; i < G.size(); i++)
{
string s;
bool iss = 1;
for (int j = 3; j < G[i].size(); j++)
{
s += G[i][j];
if ((isEVn[G[i][j]] == FU||isEVn[G[i][j]]==0)&&G[i][j]!='E')
{
iss = 0;
}
}
if (iss)
{
Select[G[i]] += Follow[G[i][0]];
if (s.size() == 1) {
First[s[0]].erase(remove(First[s[0]].begin(), First[s[0]].end(), 'E'), First[s[0]].end());
Select[G[i]] += First[s[0]];
}
if(s.size() >1)
{
First1[s].erase(remove(First1[s].begin(), First1[s].end(), 'E'), First1[s].end());
Select[G[i]] += First1[s];
}
}
else
{
if (s.size() == 1)
{
Select[G[i]] = First[s[0]];
}
if (s.size() > 1)
{
Select[G[i]] = First1[s];
}
}
}
map<string, string>::iterator it;
for (it = Select.begin(); it != Select.end(); ++it) {
string ss = it->second;
string sss;
for (int i = 0; i < ss.size(); i++)
{
if (-1 == sss.find(ss[i]))
{
sss += ss[i];
}
}
Select[it->first] = sss;
}
cout << "select集" << endl;
for (it = Select.begin(); it != Select.end(); ++it)
{
cout << it->first << " " << it->second << endl;
}
cout << "_________________" << endl;
}
第五步 构造预测分析表
对每个终结符或‘#’号用a表示。
若a∈Select(A->
α
\alpha
α),则把A->
α
\alpha
α放到M[A][
α
\alpha
α]中。
把所有无定义的M[A][
α
\alpha
α]标上出错标记。
void makeanlysistable()
{
Vt.push_back('#');
for (int i = 0; i < Vt.size(); i++)
{
map<string, string>::iterator it;
for (it = Select.begin(); it != Select.end(); it++)
{
if (Select[it->first].find(Vt[i])!=string::npos)
{
Anlysis[it->first[0]][Vt[i]] = it->first;
}
}
}
cout << "______________________" << endl;
cout << "分析表" << endl;
map<char, map<char, string>>::iterator its;
for (its = Anlysis.begin(); its != Anlysis.end(); its++)
{
map<char, string>temp(its->second);
map<char, string>::iterator it=temp.begin();
for (; it != temp.end(); it++)
{
cout << its->first << " " << it->first << " " << it->second << endl;
}
}
}
第六步 构造分析栈
void finally(string s)
{
stk.push('#');
stk.push('A');
int i = 0;
while(i<s.size()){
string temp;
char c = stk.top();
if (s[i] != c)
{
if (Anlysis[c][s[i]].size() == 0)
{
cout << "error" << endl;
break;
}
for (int j = 0; j < Anlysis[c][s[i]].size(); j++)
{
if (j >= 3)
{
temp += Anlysis[c][s[i]][j];
}
}
stk.pop();
if (temp[0] != 'E') {
for (int t = temp.size() - 1; t >= 0; t--)
{
stk.push(temp[t]);
}
}
}
else
{
if (c == '#' && s[i] == '#')
{
cout << "acc" << endl;
break;
}
stk.pop();
i++;
}
}
}
总结
把上面所有代码综合到一起
#include<iostream>
#include<ctype.h>
#include<vector>
#include<map>
#include<string>
#include<algorithm>
#include <set>
#include <stack>
using namespace std;
enum
{
FU, SH, WD
};
//规定E为空字符
vector<char>Vn;//非终结符
vector<char>Vt;//终结符
vector<char>V;//文法字符
vector<string>G;//文法
vector<string>G1;//文法副本
map<char, int>isEVn;//非终结符标记数组
map<char, string>First;//每个文法符号的first集
map<string, string>First1;//每个字符串的first集
map<char, string>Follow;//每个非终结符的follow集
map<string, string>Select;//select集
map<char,map<char,string>>Anlysis;// 分析表
stack<char>stk;
string input;
//第一步 输入文法与初始化
void inputContextRule()
{
while (cin >> input)
{
if (input == "#") break;
G.push_back(input);
G1.push_back(input);
}
int len = G1.size();
for (int i = 0; i < len; i++)
{
for (int j = 0; j < G1[i].size(); j++)
{
if (G1[i][j] >= 'A' && G1[i][j] <= 'Z' && G1[i][j] != 'E') { Vn.push_back(G1[i][j]); isEVn[G1[i][j]] = WD; }
if ((G1[i][j] > 'Z' || G1[i][j] < 'A')&&G1[i][j]!='|'&&G1[i][j] != '-' && G1[i][j] != '>') Vt.push_back(G1[i][j]);
}
}
//去重
set<int>se(Vt.begin(), Vt.end());
Vt.assign(se.begin(), se.end());
set<int>s(Vn.begin(), Vn.end());
Vn.assign(s.begin(), s.end());
}
void scamFuc()
{
for (int i = 0; i < G1.size(); i++)
{
for (int j = 3; j < G1[i].size(); j++)
{
if ((G1[i][j] > 'Z' || G1[i][j] < 'A') && G1[i][j] != '|')
{
G1[i]="";
break;
}
}
}
int lenVn = Vn.size();
for (int i = 0; i < lenVn; i++)
{
bool isexit = 0;
for (int j = 0; j < G1.size(); j++)
{
if (Vn[i] == G1[j][0]) {
isexit = 1;
break;
}
}
if (!isexit) {
isEVn[Vn[i]] = FU;
}
}
for (int i = 0; i < G1.size(); i++)
{
if (G[i].size() == 4 && G[i][3] == 'E')
{
isEVn[G[i][0]] = SH;
for (int j = 0; j < G1.size(); j++)
{
if (G1[j][0] == G[i][0])
{
G1[j] = "";
}
}
}
}
}
void scamRight()
{
for (int i = 0; i < G1.size(); i++)
{
for (int j =3; j < G1[i].size(); j++)
{
if (G1[i][j] >= 'A' && G1[i][j] <= 'Z' && G1[i][j] != 'E' && isEVn[G1[i][j]] == SH)
{
char ch1 = G1[i][j];
G1[i][j] = ' ';
string se;
bool isk = 1;
for (int t = j; t < G[i].size(); t++)
{
if (G1[i][j] != ' ')
{
isk = 0;
}
}
if (isk && G1[i][j - 1] == '>')
{
isEVn[G1[i][0]] = SH;
for (int k = 0; k < G1.size(); k++)
{
if (G1[k][0] == ch1)
{
G1[k] = "";
}
}
}
}
if (G1[i][j] >= 'A' && G1[i][j] <= 'Z' && G1[i][j] != 'E' && isEVn[G1[i][j]] == FU)
{
bool isAlldel = 0;
char ch = G1[i][0];
G1[i] = "";
for (int k = 0; k < G1.size(); k++)
{
for (int t = 0; t < G1[k].size(); t++)
{
if (ch == G1[k][0])
{
isAlldel = 1;
break;
}
}
}
if (!isAlldel) {
isEVn[ch] = FU;
}
}
}
}
}
void OneStep() {
inputContextRule();
scamFuc();
for (int i = 0; i < 3; i++) {
scamRight();
}
cout << "______________"<< endl;
map<char, int>::iterator it;
for (it = isEVn.begin(); it != isEVn.end(); ++it) {
cout << it->first << ' ' << it->second << endl;
}
cout << "______________" << endl;
}
//第二步 求First集
void SumV() {
int isexit;
for (int i = 0; i < Vn.size(); i++)
{
if (0 == (isexit = count(V.begin(), V.end(), Vn[i])))
{
V.push_back(Vn[i]);
}
}
for (int i = 0; i < Vt.size(); i++)
{
if (0 == (isexit = count(V.begin(), V.end(), Vt[i])))
{
V.push_back(Vt[i]);
}
}
}
void calSingleFirst()
{
int counts;
for (int i =0;i< V.size(); i++)
{
if (0 != (counts = count(Vt.begin(), Vt.end(), V[i])))
{
First[V[i]] += V[i];
}
if (0 != (counts = count(Vn.begin(), Vn.end(), V[i])))
{
for (int j = 0; j < G.size(); j++)
{
if (V[i] == G[j][0]) {
if (G[j][2] == '>' && (G[j][3] > 'Z' || G[j][3] < 'A') && G[j][3] != '|')
{
First[V[i]] += G[j][3];
}
if (G[j][2] == '>' && G[j][3] == 'E')
{
First[V[i]] += "E";
}
}
}
}
}
for (int j = 0; j < G.size(); j++)
{
bool isall = 1;
for (int k = 0; k < G[j].size(); k++)
{
if (G[j][k]>= 'A' && G[j][k]<='Z'){}
else if(G[j][k] == '-' || G[j][k] == '>' || G[j][k] == '|' || G[j][k] == '*' || G[j][k] == '(' || G[j][k] == ')'|| G[j][k] == '+'){}
else if (G[j][k] == 'E')
{
isall = 0;
break;
}
else
{
isall = 0;
break;
}
}
if (isall)
{
bool isall1 = 1;
for (int i = 3; i < G[j].size(); i++)
{
if (isEVn[G[j][i]] != SH)
{
isall1 = 0;
break;
}
}
if (isall1)
{
for (int i = 3; i < G[j].size(); i++)
{
First[G[j][0]] += First[G[j][i]];
}
First[G[j][0]] += 'E';
}
else
{
for (int i = 3; i < G[j].size(); i++)
{
if (isEVn[G[j][i]] == SH)
{
First[G[j][i]].erase(remove(First[G[j][i]].begin(), First[G[j][i]].end(), 'E'), First[G[j][i]].end());
First[G[j][0]] += First[G[j][i]];
First[G[j][i]] += "E";
}
else
{
First[G[j][0]] += First[G[j][i]];
break;
}
}
}
}
}
}
void calsMultiFirst()
{
for (int i = 0; i < G.size(); i++)
{
string s;
int k = 3;
while (k<G[i].size())
{
s += G[i][k];
k++;
}
if (isEVn[s[0]] == FU)
{
First1[s] = First[s[0]];
}
bool isall2 = 1;
int saveks;
for (int ks = 0; ks < s.size(); ks++)
{
if (-1 == First[s[ks]].find("E"))
{
isall2 = 0;
saveks = ks;
break;
}
}
if (isall2)
{
for (int m = 0; m < s.size(); m++)
{
First1[s] = First1[s] + First[s[m]];
}
First1[s] = First1[s] + "E";
}
else
{
for (int t = 0; t < saveks; t++)
{
First[s[t]].erase(remove(First[s[t]].begin(), First[s[t]].end(), 'E'), First[s[t]].end());
First1[s] = First1[s] + First[s[t]];
First[s[t]] += "E";
}
First1[s] += First[s[saveks]];
}
}
}
void TwoStep()
{
SumV();
for (int i = 0; i < 3; i++)
{
calSingleFirst();
}
map<char, string>::iterator it;
for (it = First.begin(); it != First.end(); ++it) {
string ss = it->second;
string sss;
if (it->first == 'E' ) First[it->first] += "E";
for (int i = 0; i < ss.size(); i++)
{
if (-1 == sss.find(ss[i]))
{
sss += ss[i];
}
}
First[it->first] = sss;
}
cout << "单字符first集" << endl;
for (it = First.begin(); it != First.end(); ++it) {
cout << it->first << ' ' << it->second << endl;
}
cout << "______________" << endl;
for (int i = 0; i < 3; i++)
{
calsMultiFirst();
}
map< string, string>::iterator its;
for (its = First1.begin(); its != First1.end(); ++its) {
string ss = its->second;
string sss;
for (int i = 0; i < ss.size(); i++)
{
if (-1 == sss.find(ss[i]))
{
sss += ss[i];
}
}
First1[its->first] = sss;
}
cout << "字符串frist集" << endl;
for (its = First1.begin(); its != First1.end(); ++its) {
cout << its->first << ' ' << its->second << endl;
}
cout << "______________" << endl;
}
//第三步 求Follow集
void initFollow() {
Follow['A'] = "#";
for (int i = 0; i < Vn.size(); i++)
{
if (Vn[i] != 'A')
{
Follow[Vn[i]] = "";
}
}
}
void calFollow()
{
for (int i = 0; i < Vn.size(); i++)
{
for (int j = 0; j < G.size(); j++)
{
if (G[j][0] == Vn[i])
{
for (int k = 3; k < G[j].size(); k++)
{
string s;
if (G[j][k] >= 'A' && G[j][k] <= 'Z'&& G[j][k]!='E')
{
for (int t = k+1; t < G[j].size(); t++)
{
s += G[j][t];
}
bool isa = 1;
for (int n = 0; n < s.size(); n++)
{
if (isEVn[s[n]] == 0)
{
isa = 0;
//break;
}
}
if (s.size() > 1)
{
if (First1[s] != "") {
for (int m = 0; m < First1[s].size(); m++)
{
if (First1[s][m] != 'E') Follow[G[j][k]] += First1[s][m];
}
if (isa)
{
Follow[G[j][k]] += Follow[Vn[i]];
}
//break;
}
}
else
{
if (s.size() == 0)
{
Follow[G[j][k]] += Follow[Vn[i]];
//break;
}
if (First[s[0]] != "")
{
for (int m = 0; m < First[s[0]].size(); m++)
{
if (First[s[0]][m] != 'E') Follow[G[j][k]] += First[s[0]][m];
}
if (isa)
{
Follow[G[j][k]] += Follow[Vn[i]];
}
// break;
}
}
}
}
}
}
}
}
void ThridStep()
{
initFollow();
for (int i = 0; i <5; i++)
{
calFollow();
}
map<char, string>::iterator it;
for (it = Follow.begin(); it != Follow.end(); ++it) {
string ss = it->second;
string sss;
for (int i = 0; i < ss.size(); i++)
{
if (-1 == sss.find(ss[i]))
{
sss += ss[i];
}
}
Follow[it->first] = sss;
}
cout << "非终结符的follow集" << endl;
for (it = Follow.begin(); it != Follow.end(); ++it)
{
cout << it->first << " " << it->second << endl;
}
cout << "_________________" << endl;
}
//第四步 求select集
void calselect()
{
for (int i = 0; i < G.size(); i++)
{
string s;
bool iss = 1;
for (int j = 3; j < G[i].size(); j++)
{
s += G[i][j];
if ((isEVn[G[i][j]] == FU||isEVn[G[i][j]]==0)&&G[i][j]!='E')
{
iss = 0;
}
}
if (iss)
{
Select[G[i]] += Follow[G[i][0]];
if (s.size() == 1) {
First[s[0]].erase(remove(First[s[0]].begin(), First[s[0]].end(), 'E'), First[s[0]].end());
Select[G[i]] += First[s[0]];
}
if(s.size() >1)
{
First1[s].erase(remove(First1[s].begin(), First1[s].end(), 'E'), First1[s].end());
Select[G[i]] += First1[s];
}
}
else
{
if (s.size() == 1)
{
Select[G[i]] = First[s[0]];
}
if (s.size() > 1)
{
Select[G[i]] = First1[s];
}
}
}
map<string, string>::iterator it;
for (it = Select.begin(); it != Select.end(); ++it) {
string ss = it->second;
string sss;
for (int i = 0; i < ss.size(); i++)
{
if (-1 == sss.find(ss[i]))
{
sss += ss[i];
}
}
Select[it->first] = sss;
}
cout << "select集" << endl;
for (it = Select.begin(); it != Select.end(); ++it)
{
cout << it->first << " " << it->second << endl;
}
cout << "_________________" << endl;
}
//构造分析表
void makeanlysistable()
{
Vt.push_back('#');
for (int i = 0; i < Vt.size(); i++)
{
map<string, string>::iterator it;
for (it = Select.begin(); it != Select.end(); it++)
{
if (Select[it->first].find(Vt[i])!=string::npos)
{
Anlysis[it->first[0]][Vt[i]] = it->first;
}
}
}
cout << "______________________" << endl;
cout << "分析表" << endl;
map<char, map<char, string>>::iterator its;
for (its = Anlysis.begin(); its != Anlysis.end(); its++)
{
map<char, string>temp(its->second);
map<char, string>::iterator it=temp.begin();
for (; it != temp.end(); it++)
{
cout << its->first << " " << it->first << " " << it->second << endl;
}
}
}
//分析栈
void finally(string s)
{
stk.push('#');
stk.push('A');
int i = 0;
while(i<s.size()){
string temp;
char c = stk.top();
if (s[i] != c)
{
if (Anlysis[c][s[i]].size() == 0)
{
cout << "error" << endl;
break;
}
for (int j = 0; j < Anlysis[c][s[i]].size(); j++)
{
if (j >= 3)
{
temp += Anlysis[c][s[i]][j];
}
}
stk.pop();
if (temp[0] != 'E') {
for (int t = temp.size() - 1; t >= 0; t--)
{
stk.push(temp[t]);
}
}
}
else
{
if (c == '#' && s[i] == '#')
{
cout << "acc" << endl;
break;
}
stk.pop();
i++;
}
}
}
//主程序
int main()
{
OneStep();
TwoStep();
ThridStep();
calselect();
makeanlysistable();
string inputs;
cout << endl;
while (true)
{
cout << "请输入串:" << endl;
cin >> inputs;
finally(inputs);
cout << endl;
}
return 0;
}
可以参考《编译原理》第三版 ——清华大学出版社73-77,92-95,上面所有代码是根据上面的规则实现的。
毕竟水平有限,写的有错误的地方还请见谅。