// МП для КС-грамматик public myMp(myGrammar KCgrammar) : base(new ArrayList() { "q" }, KCgrammar.T, new ArrayList() { }, "q") { this.Gamma = new ArrayList(); this.Z = new Stack(); foreach (string v1 in KCgrammar.V) // магазинные символы { Gamma.Add(v1); } foreach (string t1 in KCgrammar.T) { Gamma.Add(t1); } Q0 = Q[0].ToString(); // начальное состояние Z.Push(KCgrammar.S0); // начальный символ в магазине F = new ArrayList(); // пустое множество заключительных состояний DeltaQSigmaGamma delta = null; foreach (string v1 in KCgrammar.V) { // сопоставление правил с отображениями ArrayList q1 = new ArrayList(); ArrayList z1 = new ArrayList(); foreach (Prule rule in KCgrammar.Prules) { if (rule.leftNoTerm == v1) { Stack zb = new Stack(); ArrayList rr = new ArrayList(rule.rightChain); rr.Reverse(); foreach (string s in rr) { zb.Push(s); } z1.Add(zb); q1.Add(Q0); } } delta = new DeltaQSigmaGamma(Q0, "e", v1, q1, z1); DeltaList.Add(delta); } foreach (string t1 in KCgrammar.T) { Stack e = new Stack(); e.Push("e"); delta = new DeltaQSigmaGamma(Q0, t1, t1, new ArrayList() { Q0 }, new ArrayList() { e }); DeltaList.Add(delta); } }
public void ComputeFirstSets(myGrammar grammar) { for (int i = 0; i < grammar.T.Count; i++) { FirstSet[(string)grammar.T[i]] = new HashSet <string>() { grammar.T[i].ToString() } } ; // FIRST[c] = {c}*/ for (int i = 0; i < grammar.V.Count; i++) { FirstSet[(string)grammar.V[i]] = new HashSet <string>(); //First[x] = empty list } bool changes = true; while (changes) { changes = false; for (int i = 0; i < grammar.Prules.Count; ++i) { // Для каждого правила X-> Y0Y1…Yn Prule currRule = (Prule)(grammar.Prules[i]); string X = currRule.LeftNoTerm; List <string> Y = currRule.rightChain.Cast <string>().ToList(); for (int k = 0; k < Y.Count; k++) { foreach (string currFirstSymb in (HashSet <string>)FirstSet[Y[k]]) { if (((HashSet <string>)FirstSet[X]).Add(currFirstSymb)) //Добавить а в FirstSets[X] { changes = true; } } if (!((HashSet <string>)FirstSet[Y[k]]).Contains("")) { break; } } } } // пока вносятся изменения }
public void ComputeFollowSets(myGrammar grammar) { for (int i = 0; i < grammar.V.Count; i++) { FollowSet[(string)grammar.V[i]] = new HashSet <string>(); } FollowSet[G.S0] = new HashSet <string>() { "" }; bool changes = true; while (changes) { changes = false; for (int i = 0; i < grammar.Prules.Count; ++i) { // Для каждого правила X-> Y0Y1…Yn Prule currRule = (Prule)(grammar.Prules[i]); List <string> rightChain = currRule.RightChain.Cast <string>().ToList(); for (int indexOfSymbol = 0; indexOfSymbol < rightChain.Count; ++indexOfSymbol) { string currSymbol = rightChain[indexOfSymbol]; if (G.T.Contains(currSymbol)) { continue; } if (indexOfSymbol == rightChain.Count - 1) { foreach (string currFollowSymbol in (HashSet <string>)FollowSet[currRule.LeftNoTerm]) { if (((HashSet <string>)FollowSet[rightChain[indexOfSymbol]]).Add(currFollowSymbol)) { changes = true; } } } else { List <string> currFirst = First(rightChain[indexOfSymbol + 1]); bool epsFound = false; foreach (var currFirstSymbol in currFirst) { if (currFirstSymbol != "") { if (((HashSet <string>)FollowSet[rightChain[indexOfSymbol]]).Add(currFirstSymbol)) { changes = true; } } else { epsFound = true; } } if (epsFound) { foreach (string currFollowSymbol in (HashSet <string>)FollowSet[currRule.LeftNoTerm]) { if (((HashSet <string>)FollowSet[rightChain[indexOfSymbol]]).Add(currFollowSymbol)) { changes = true; } } } } } } } }
public LLParser(myGrammar grammar) //конструктор { G = grammar; Table = new DataTable("ManagerTable"); Stack = new Stack <string>(); //создаем стек(магазин) для символов // Создадим таблицу синтаксического анализа для этой грамматики // Определим структуру таблицы Table.Columns.Add(new DataColumn("VT", typeof(String))); Console.WriteLine("Создадим таблицу. Сначала создадим по столбцу для каждого из этих терминалов: "); foreach (string termSymbol in G.T) { Console.Write(termSymbol); Console.Write(", "); Table.Columns.Add(new DataColumn(termSymbol, typeof(Prule))); } Console.WriteLine("\nТакже создаем строку для Эпсилон"); Table.Columns.Add(new DataColumn("EoI", typeof(Prule))); // Epsilon ComputeFirstSets(grammar); // Вычисляем множество First ComputeFollowSets(grammar); // Вычисляем множество Follow for (int i = 0; i < grammar.V.Count; i++) // Рассмотрим последовательно все нетерминалы { DataRow workRow = Table.NewRow(); //Новая строка workRow["VT"] = (string)grammar.V[i]; Console.Write("Рассмотрим нетерминал "); Console.Write((grammar.V[i])); Console.Write("\n"); List <Prule> rules = getRules((string)grammar.V[i]); // Получим все правила, соответствующие текущему нетерминалу foreach (var rule in rules) { List <string> currFirstSet = First(rule.RightChain.Cast <string>().ToList()); foreach (var firstSymbol in currFirstSet) { if (firstSymbol != "") { // Добавить в таблицу Console.Write(" Первый символ правила "); Console.Write(rule.LeftNoTerm); Console.Write(" -> "); for (int j = 0; j < rule.RightChain.Count; j++) { Console.Write(rule.RightChain[j]); } Console.Write(" - "); Console.WriteLine(firstSymbol); workRow[firstSymbol] = rule; Console.Write(" Это правило заносим в таблицу на пересечении строки нетерминала "); Console.Write(rule.LeftNoTerm); Console.Write(" и столбца терминала "); Console.WriteLine(firstSymbol); Console.Write("\n"); } else { List <string> currFollowSet = Follow(rule.leftNoTerm); foreach (var currFollowSymb in currFollowSet) { string currFollowSymbFix = (currFollowSymb == "") ? "EoI" : currFollowSymb; workRow[currFollowSymbFix] = rule; } } } } Table.Rows.Add(workRow); } }