//刚开始代码中用的是Ne,现在改为toEpsilon
Dictionary<char, bool> toEpsilon = new Dictionary<char, bool>();//是否能推出epsilon
void ComputeEpsilon() {//第一步求出能推出epsilon的非终结符
Dictionary<char, List> curr = LR.ToDictionary(entry => entry.Key, entry => entry.Value.ToList());
Dictionary<char, int> record2 = new Dictionary<char, int>(record);//记录以某一非终结符为左部的产生式的数量
foreach (KeyValuePair<char, List> s in curr) {
//产生式:A->BC,s1:BC s2:A
List s1 = s.Value;
char s2 = s.Key;
for (int i = 0; i < s1.Count; i++) {
if (s1[i].Length == 1 && s1[i][0] == '=') {//如果产生式右侧只有epsilon
toEpsilon[s2] = true;
curr[s2] = new List() { "" };//将所有此非终结符的产生式置空
break;
}
for (int j = 0; j < s1[i].Length; j++) {
if (VT.Contains(s1[i][j])) {//为非终结符
curr[s2][i] = "";//此产生式删除
record2[s2]--;//s2的产生式减1
if (record2[s2] == 0) {//如果s2的产生式都被删除,则为false
toEpsilon[s2] = false;
}
}
}
}
}
int judge = 0;
while (judge <= 20) {//第三步,迭代20次
foreach (KeyValuePair<char, List> s in curr) {
List s1 = s.Value;
char s2 = s.Key;
for (int i = 0; i < s1.Count; i++) {
int len = s1[i].Length;//用len来记录该产生式右部剩下的字符数
for (int j = 0; j < s1[i].Length; j++) {
if (toEpsilon.ContainsKey(s1[i][j]) && VN.Contains(s1[i][j])) {//为非终结符
if (toEpsilon[s1[i][j]]) {
len--;//删去该终结符,右部字符数-1
if (len == 0) {//全部删了,则为true
toEpsilon[s2] = true;
break;
}
}
else {
curr[s2][i] = "";//删去该产生式
record2[s2]--;
if (record2[s2] == 0) {
toEpsilon[s2] = false;
break;
}
}
}
}
}
}
judge++;
}