// 创建LR(1)文法的分析表 private void calcAnalyzeList() { // 求 移进 列 var anaList = new List <KeyValuePair <string, List <string> > >(); List <string> rowData = new List <string>() { }; rowData.Add("符号"); for (int i = 0; i < graphMatrixCount; i++) { rowData.Add(i.ToString()); } anaList.Add(new KeyValuePair <string, List <string> >("状态", rowData)); List <char> text = new List <char>(); foreach (char c in page.terminator.Text) { text.Add(c); } text.Sort(); text.Add('#'); int indexCount = 0; foreach (char c in text) // 枚举每个非终结符(对应ACTION列) { rowData = new List <string>() { }; rowData.Add(c.ToString()); for (int i = 0; i < graphMatrixCount; i++) { rowData.Add(""); } for (int i = 0; i < graphMatrixCount; i++) { for (int j = 0; j < graphMatrixCount; j++) { if (graphMatrix[i, j] == c) { rowData[i + 1] = "S" + j; } } } anaList.Add(new KeyValuePair <string, List <string> >("ACTION " + indexCount++, rowData)); } // 求 规约 列 foreach (string line in page.lstProduce.Items) // HASH产生式方便由产生式确定产生式所在下标 { int pos = line.IndexOf(':'); getIndexByProduct[line.Substring(pos + 1).Replace("ε", "")] = Int32.Parse(line.Substring(0, pos)); } flag = true; for (int i = 0; i < allStates.Count; i++) { foreach (var item in allStates[i].items) { if (item.Key.EndsWith("●")) { int index = getIndexByProduct[item.Key.Substring(0, item.Key.Length - 1)]; foreach (char c in item.Value) { string append = (index > 0) ? ("r" + index) : "acc"; int j; for (j = 0; j < anaList.Count; j++) { if (anaList[j].Value[0].Equals(c.ToString())) { break; } } if (anaList[j].Value[i + 1].Length > 0) { anaList[j].Value[i + 1] += "/" + append; if (c != '#' || i + 1 != 1) // 不是接受项则产生冲突 { flag = false; } } else { anaList[j].Value[i + 1] = append; } } } } } // 求 GOTO 列 text.Clear(); for (int i = 1; i < page.nterminator.Text.Length; i++) { text.Add(page.nterminator.Text[i - 1]); } foreach (char c in text) // 与移进处理类似 { rowData = new List <string>() { }; rowData.Add(c.ToString()); for (int i = 0; i < graphMatrixCount; i++) { rowData.Add(""); } for (int i = 0; i < graphMatrixCount; i++) { for (int j = 0; j < graphMatrixCount; j++) { if (graphMatrix[i, j] == c) { rowData[i + 1] = j.ToString(); } } } anaList.Add(new KeyValuePair <string, List <string> >("GOTO " + indexCount++, rowData)); } // 作为HashMap、转置拷贝到全局(用于分析例句) foreach (var pair in anaList) { if (!pair.Key.Equals("状态")) { for (int i = 1; i < pair.Value.Count; i++) { if (!analyzeList.ContainsKey(i - 1)) { analyzeList[i - 1] = new Dictionary <char, string>(); } analyzeList[i - 1][pair.Value[0][0]] = pair.Value[i]; } } } page.tbLRList.ItemsSource = DataSourceCreator.ToDataSource(anaList); if (!flag) { MessagePage.Show("由于冲突的产生,所以该文法不符合LR(1)文法!"); } }
// 构造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); }
// 对语句进行分析与验证 private void calcAnalyzeCode() { if (!flag) { page.legal.Text = "无解"; return; } string text = page.sentence.Text; int nStep = 1; List <string> step = new List <string>() { "(" + nStep++.ToString() + ")" }, stateStack = new List <string>() { "0" }, operStack = new List <string>() { "#" }, inputString = new List <string>() { text + '#' }, actionOper = new List <string>(), gotoOper = new List <string>(); // 从第一步开始求解分析过程 while (flag) { // 当前状态s,当前字符c int s = Int32.Parse(stateStack[stateStack.Count - 1].Substring(stateStack[stateStack.Count - 1].LastIndexOf(',') + 1)); char c = inputString[inputString.Count - 1][0]; string got = analyzeList[s][c]; if (got.Length == 0) { flag = false; actionOper.Add("出错"); gotoOper.Add(""); break; } if (got.Contains("acc")) // 遇到'#'且可以为acc则一定为接受 { actionOper.Add("接受"); gotoOper.Add(""); break; } char type = got[0]; int next = Int32.Parse(got.Substring(1)); step.Add("(" + nStep++.ToString() + ")"); if (type == 'S') // 移进 { actionOper.Add("移进 " + next); gotoOper.Add(""); stateStack.Add(stateStack[stateStack.Count - 1] + "," + next); operStack.Add(operStack[operStack.Count - 1] + c); inputString.Add(inputString[inputString.Count - 1].Substring(1)); } else // 规约 { actionOper.Add("规约 " + next); string line = (string)page.lstProduce.Items[next]; line = line.Substring(line.IndexOf(':') + 1).Replace("ε", ""); char left = line[0]; string right = line.Substring(4); string stackCut = stateStack[stateStack.Count - 1]; for (int i = 0; i < right.Length; i++) { stackCut = stackCut.Remove(stackCut.LastIndexOf(',')); } int new_top = Int32.Parse(stackCut.Substring(stackCut.LastIndexOf(',') + 1)); // 弹斩后栈顶 int target = Int32.Parse(analyzeList[new_top][left]); // 获取GOTO目标 stateStack.Add(stackCut + "," + target); if (right.Length > 0) { operStack.Add(operStack[operStack.Count - 1].Remove(operStack[operStack.Count - 1].Length - right.Length) + left); } else { operStack.Add(operStack[operStack.Count - 1] + left); } inputString.Add(inputString[inputString.Count - 1]); gotoOper.Add("转至 " + target); } } page.legal.Text = (flag) ? "正确" : "错误"; var showAnalyze = new List <KeyValuePair <string, List <string> > >(); showAnalyze.Add(new KeyValuePair <string, List <string> >("步骤", step)); showAnalyze.Add(new KeyValuePair <string, List <string> >("状态栈", stateStack)); showAnalyze.Add(new KeyValuePair <string, List <string> >("符号栈", operStack)); showAnalyze.Add(new KeyValuePair <string, List <string> >("输入串", inputString)); showAnalyze.Add(new KeyValuePair <string, List <string> >("ACTION", actionOper)); showAnalyze.Add(new KeyValuePair <string, List <string> >("GOTO", gotoOper)); page.tbAnalyze.ItemsSource = DataSourceCreator.ToDataSource(showAnalyze); }
// 计算FIRST,FOLLOW集 private void calcFirstAndFollow() { // 求 FIRST 集 flag = true; while (flag) { flag = false; visited.Clear(); foreach (char c in page.nterminator.Text) { first_dfs(c); } } // 求 FOLLOW 集 follow[(char)page.cbBegin.SelectedItem] = new List <char>() { '#' }; flag = true; while (flag) { flag = false; visited.Clear(); foreach (char c in page.nterminator.Text) { follow_dfs(c); } } // 构造二维表并显示 var dicFfset = new List <KeyValuePair <string, List <string> > >(); List <string> ntList = new List <string>(), firstList = new List <string>(), followList = new List <string>(); foreach (char c in page.nterminator.Text) { // 列表 ntList.Add(c.ToString()); StringBuilder sb = new StringBuilder(); // 构造FIRST集 sb.Remove(0, sb.Length); first[c].Sort(); foreach (char t in first[c]) { sb.Append(t); sb.Append(' '); } firstList.Add(sb.ToString()); // 构造FOLLOW集 sb.Remove(0, sb.Length); follow[c].Sort(); foreach (char t in follow[c]) { sb.Append(t); sb.Append(' '); } followList.Add(sb.ToString()); } dicFfset.Add(new KeyValuePair <string, List <string> >("非终结符", ntList)); dicFfset.Add(new KeyValuePair <string, List <string> >("FIRST 集", firstList)); dicFfset.Add(new KeyValuePair <string, List <string> >("FOLLOW 集", followList)); page.tbFfset.ItemsSource = DataSourceCreator.ToDataSource(dicFfset); }