// 扩充计算当前产生式组的闭包 public EnclosedState calcEnclosed(EnclosedState es) { List <KeyValuePair <string, List <char> > > queue = new List <KeyValuePair <string, List <char> > >(); foreach (var item in es.items) // 所有产生式入队 { queue.Add(item); } for (int i = 0; i < queue.Count; i++) { var item = queue[i]; int pos = item.Key.IndexOf('●') + 1; if (pos < item.Key.Length) { if (!isTerminator(item.Key[pos])) // 非终结符item.Key[pos]扩充产生式 { foreach (string text in page.lstProduce.Items) { if (text[text.IndexOf(':') + 1] == item.Key[pos]) // 要扩充的一项产生式 { string extend = text.Substring(text.IndexOf(':') + 1).Replace(" → ", " → ●").Replace("ε", ""); List <char> suffix = new List <char>(); bool append = false; if (pos + 1 == item.Key.Length) // 该非终结符在结尾,则对于'ba'要添加'a' { append = true; } for (int j = pos + 1; j < item.Key.Length; j++) { if (isTerminator(item.Key[j]) && !suffix.Contains(item.Key[j])) // 如果是终结符则直接确定附加项 { suffix.Add(item.Key[j]); break; } else // 如果是非终结符则添加FIRST集到附加项(包含ε则继续) { bool blank = false; foreach (char c in first[item.Key[j]]) { if (c == 'ε') { blank = true; } else if (!suffix.Contains(c)) { suffix.Add(c); } } if (!blank) { break; } if (j + 1 == item.Key.Length) // 最后一个可行非终结符还有ε { append = true; } } } if (append) // 原有附加项并到扩展项 { foreach (char c in item.Value) { if (!suffix.Contains(c)) { suffix.Add(c); } } } int k; for (k = 0; k < queue.Count; k++) // 寻找完全重复项 { if (queue[k].Key.Equals(extend) && queue[k].Value.Count == suffix.Count) { int l; suffix.Sort(); for (l = 0; l < suffix.Count; l++) { if (suffix[l] != queue[k].Value[l]) { break; } } if (l >= suffix.Count) // 完全相等 { break; } } } if (k >= queue.Count) // 没有找到完全相等项,确定扩展一项(队列顺序限制,包括对“半重复”产生式也要进队) { queue.Add(new KeyValuePair <string, List <char> >(extend, suffix)); } } } } } } EnclosedState esbuild = new EnclosedState(); for (int i = 0; i < queue.Count; i++) { if (esbuild.items.ContainsKey(queue[i].Key)) // 压缩队中产生式,若含有相同递推式则合并附加项,否则新建【产生式|向前搜索符】元组 { foreach (char c in queue[i].Value) { if (!esbuild.items[queue[i].Key].Contains(c)) { esbuild.items[queue[i].Key].Add(c); } } } else { esbuild.items.Add(queue[i].Key, queue[i].Value); } } return(esbuild); }
// 构造LR(1)文法的DFA private void calcDefiniteFA() { int count = 0; List <string> extList = new List <string>(); extList.Add(count++.ToString() + ":" + "Φ → " + page.cbBegin.SelectedItem); foreach (string line in page.lstProduce.Items) { extList.Add(count++.ToString() + ":" + line[0] + " → " + line.Substring(4)); } page.lstProduce.Items.Clear(); foreach (string line in extList) { page.lstProduce.Items.Add(line); } page.nterminator.Text += 'Φ'; var init_state = new EnclosedState(); init_state.items.Add("Φ → ●" + page.cbBegin.SelectedItem, new List <char>() { '#' }); init_state = calcEnclosed(init_state); allStates.Add(init_state); List <List <KeyValuePair <int, char> > > release = new List <List <KeyValuePair <int, char> > >(); // release[i][j]记录第i个状态可以通过字符release[i][j].Value推出第release[i][j].Key个状态 for (int i = 0; i < allStates.Count; i++) { var front = allStates[i].items; var graphAdj = new List <KeyValuePair <int, char> >(); var enableChr = new List <char>(); // 对推新状态的途径字符判重 foreach (var pair in front) // 找出所有不重复可推状态 { int pos = pair.Key.IndexOf('●') + 1; if (pos < pair.Key.Length && !enableChr.Contains(pair.Key[pos])) { char c = pair.Key[pos]; enableChr.Add(c); // 对推新状态的途径字符判重 // 对经过c字符转向新状态 EnclosedState esbuild = new EnclosedState(); foreach (var trans in front) // 查询当前状态所有产生式中,●后是c的条目 { int np = trans.Key.IndexOf('●') + 1; if (np < trans.Key.Length && trans.Key[np] == c) // 找到一条符合项 { string next = trans.Key.Remove(np - 1, 1).Insert(np, "●"); esbuild.items.Add(next, trans.Value); } } esbuild = calcEnclosed(esbuild); int j; for (j = 0; j < allStates.Count; j++) // 新状态已存在 { if (EnclosedState.Equals(esbuild.items, allStates[j].items)) // 判断是否完全匹配 { graphAdj.Add(new KeyValuePair <int, char>(j, c)); break; } } if (j >= allStates.Count) // 不存在新状态则创建 { graphAdj.Add(new KeyValuePair <int, char>(j, c)); allStates.Add(esbuild); } } } release.Add(graphAdj); } graphMatrixCount = allStates.Count; graphMatrix = new char[graphMatrixCount, graphMatrixCount]; for (int i = 0; i < graphMatrixCount; i++) { foreach (var j in release[i]) { graphMatrix[i, j.Key] = j.Value; } } int tot = allStates[0].items.Count; for (int i = 1; i < allStates.Count; i++) { tot = Math.Max(tot, allStates[i].items.Count); } // 显示DFA状态转换矩阵 var dfaMatrix = new List <KeyValuePair <string, List <string> > >(); List <string> stateList = new List <string>(); for (int i = 0; i < graphMatrixCount; i++) { stateList.Add("状态" + i); } dfaMatrix.Add(new KeyValuePair <string, List <string> >("DFA", stateList)); for (int i = 0; i < graphMatrixCount; i++) { stateList = new List <string>(); for (int j = 0; j < graphMatrixCount; j++) { if (graphMatrix[j, i] > 0) { StringBuilder sb = new StringBuilder(); sb.Append("从状态" + j + ":\n"); foreach (var item in allStates[j].items) { sb.Append(item.Key); sb.Append(" , "); sb.Append(item.Value[0]); for (int k = 1; k < item.Value.Count; k++) { sb.Append('/'); sb.Append(item.Value[k]); } sb.Append('\n'); } for (int l = allStates[j].items.Count; l < tot; l++) { sb.Append('\n'); } sb.Append("经过字符 " + graphMatrix[j, i] + " 转变为状态" + i + ":\n"); foreach (var item in allStates[i].items) { sb.Append(item.Key); sb.Append(" , "); sb.Append(item.Value[0]); for (int k = 1; k < item.Value.Count; k++) { sb.Append('/'); sb.Append(item.Value[k]); } sb.Append('\n'); } for (int l = allStates[i].items.Count; l < tot; l++) { sb.Append('\n'); } stateList.Add(sb.ToString()); } else { StringBuilder sb = new StringBuilder(); for (int l = 0; l <= tot; l++) { sb.Append("\n\n"); } stateList.Add(sb.ToString()); } } dfaMatrix.Add(new KeyValuePair <string, List <string> >("状态" + i, stateList)); } page.tbDfa.ItemsSource = DataSourceCreator.ToDataSource(dfaMatrix); }