public void BuildByRules(Grammar g, List<int> rules, List<Token> tokens) { List<ExpressionTreeItem> Leafs = new List<ExpressionTreeItem>(); Tokens = tokens; Leafs.Add(Root); for (int i = rules.Count - 1; i >= 0; i--) { Rule rule = g.Rules[rules[i]]; int idx = Leafs.Count - 1; while (!Leafs[idx].Value.Equals(rule.Left) && idx > 0) idx--; if (idx < 0) { System.Diagnostics.Debug.WriteLine("Error while tree building"); return; } var leaf = Leafs[idx]; Leafs.RemoveAt(idx); leaf.Value = rule.Left; leaf.Rul = rule; foreach (var child in rule.Right) { ExpressionTreeItem item = new ExpressionTreeItem(child); leaf.Children.Add(item); Leafs.Add(item); } } SetTrueLeafs(Root); LeaveOnlyNessesary(null, 0, ref Root); }
public HashSet<Situation> GetClosure(Grammar grammar, HashSet<Situation> input) { Stack<Situation> st = new Stack<Situation>(input); while (st.Count > 0) { Situation sit = st.Pop(); String B = (sit.Pos < sit.Rul.Right.Count) ? sit.Rul.Right[sit.Pos] : "lambda", beta = (sit.Pos + 1 < sit.Rul.Right.Count) ? sit.Rul.Right[sit.Pos + 1] : "lambda", a = sit.Term; if (!grammar.NonTerminals.Contains(B)) continue; HashSet<Situation> temp = new HashSet<Situation>(); foreach (var rule in grammar.Rules.Where(r => r.Left.Equals(B))) foreach (var term in GetFirstForChain(new List<String>() { beta, a })) { if (!grammar.Terminals.Contains(term)) continue; Situation nsit = new Situation(); nsit.Term = term; nsit.Pos = 0; nsit.Rul = rule; bool cont = false; foreach (var s in input) if (s.IsEqual(nsit)) cont = true; if (!cont) { temp.Add(nsit); st.Push(nsit); } } input = new HashSet<Situation>(input.Union(temp)); } return input; }
public void CountAllQs(Grammar grammar) { GetFirstForAll(grammar); TableG = new Dictionary<string, List<int>>(); TableF = new Dictionary<string, List<String>>(); foreach (var term in grammar.Terminals.Union(grammar.NonTerminals)) { if (term.Equals("lambda")) continue; TableG.Add(term, new List<int>()); } foreach (var term in grammar.Terminals) TableF.Add(term, new List<String>()); Situation start = new Situation(); start.Term = "lambda"; start.Pos = 0; start.Rul = grammar.Start; List<HashSet<Situation>> allQ = new List<HashSet<Situation>>(); allQ.Add(GetClosure(grammar, new HashSet<Situation>() { start })); int i = 0; while (i < allQ.Count) { foreach (var list in TableG.Values) list.Add(-1); foreach (var list in TableF.Values) list.Add(String.Empty); var cursit = allQ[i]; foreach (var nonterm in grammar.NonTerminals.Union(grammar.Terminals)) { if (nonterm.Equals("lambda") || nonterm.Equals("start")) continue; var gt = GoTo(grammar, cursit, nonterm); int idx = -1; for (int j = 0; j < allQ.Count; j++) if (allQ[j].IsEqual(gt)) { idx = j; break; } if ((idx == -1) && (gt.Count > 0)) { allQ.Add(gt); idx = allQ.Count - 1; } TableG[nonterm][i] = idx; } i++; } for (int j = 0; j < allQ.Count; j++) { foreach (var s in allQ[j]) { if (s.Pos == s.Rul.Right.Count) { if (s.Rul.Left.Equals("start") && s.Term.Equals("lambda")) TableF[s.Term][j] = "accept"; if (!s.Rul.Left.Equals("start")) TableF[s.Term][j] = "reduce " + grammar.Rules.FindIndex(r => r.IsEqual(s.Rul)); } else { var a = s.Rul.Right[s.Pos]; if (grammar.Terminals.Contains(a)) { int jj = TableG[a][j]; if (jj != -1) TableF[a][j] = "shift " + jj; } } } } }
public bool OneRound(Grammar grammar) { Boolean wasAdded = false; foreach (String term in grammar.Terminals) { if (!Firsts.ContainsKey(term)) { Firsts.Add(term, new HashSet<string>() { term }); wasAdded = true; } } foreach (String nonterm in grammar.NonTerminals) { if (!Firsts.ContainsKey(nonterm)) Firsts.Add(nonterm, new HashSet<string>()); if (grammar.Rules.Count(r => r.Left.Equals(nonterm) && (r.Right.Count == 1) && (r.Right[0].Equals("lambda")) && (!Firsts[nonterm].Contains("lambda"))) > 0) { Firsts[nonterm].Add("lambda"); wasAdded = true; } foreach (Rule r in grammar.Rules.Where(r => r.Left.Equals(nonterm))) { if (r.Right.Count(s => !Firsts.ContainsKey(s)) == 0) { int lastl = -1; for (int i = 0; i < r.Right.Count; i++) if (Firsts[r.Right[i]].Contains("lambda")) lastl = i; else break; if ((lastl == r.Right.Count) && !Firsts[nonterm].Contains("lambda")) { Firsts[nonterm].Add("lambda"); wasAdded = true; } else if (lastl < r.Right.Count - 1) lastl++; for (int i = 0; i <= lastl; i++) { foreach (var s in Firsts[r.Right[i]]) if (!Firsts[nonterm].Contains(s)) { Firsts[nonterm].Add(s); wasAdded = true; } } } } if (Firsts[nonterm].Count == 0) Firsts.Remove(nonterm); } return wasAdded; }
public HashSet<Situation> GoTo(Grammar grammar, HashSet<Situation> I, String X) { HashSet<Situation> J = new HashSet<Situation>(); foreach (var sit in I.Where(s => (s.Pos <= s.Rul.Right.Count) && ((s.Pos < s.Rul.Right.Count) ? s.Rul.Right[s.Pos] : "lambda").Equals(X))) { Situation ns = new Situation(); ns.Rul = sit.Rul; ns.Term = sit.Term; ns.Pos = sit.Pos + 1; foreach (var s in GetClosure(grammar, new HashSet<Situation>() { ns })) if (J.Count(j => j.IsEqual(s)) == 0) J.Add(s); } return J; }
public void GetFirstForAll(Grammar grammar) { Firsts = new Dictionary<String, HashSet<String>>(); Firsts.Add("lambda", new HashSet<string>() { "lambda" }); while (OneRound(grammar)) ; }
public void LoadRule(Grammar g, String s) { if (!s.Contains("->")) return; String left = s.Substring(0, s.IndexOf("->")); String right = s.Substring(s.IndexOf("->") + 2, s.Length - s.IndexOf("->") - 2); String action = String.Empty; if (s.Contains('`')) action = s.Substring(s.IndexOf('`') + 1); List<Int32> p = new List<int>(); foreach (var param in action.Split('{')) if (param.Contains('}')) p.Add(Int32.Parse(param.Substring(0, param.IndexOf('}')))); if (action.Contains('{')) action = action.Substring(0, action.IndexOf('{')); var terms = left.Split(new char[] { '[' }, StringSplitOptions.RemoveEmptyEntries); String lft = String.Empty; if (terms.Count() > 0 && terms[0].Contains("]")) { lft = terms[0].Substring(0, terms[0].IndexOf(']')); g.NonTerminals.Add(lft); } var rls = right.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (String rule in rls) { Rule r = new Rule(lft); r.Action = action; r.Params = p; foreach (String term in rule.Split(new char[] { '[' }, StringSplitOptions.RemoveEmptyEntries)) { if (term.Contains("]")) { var t = term.Substring(0, term.IndexOf(']')); g.Terminals.Add(t); r.Right.Add(t); } } g.Rules.Add(r); } }
public void AnalyzeString(Grammar g, ComplexMachine m, ExpressionTree e, String s, Helper h) { List<Int32> rules = new List<int>(); List<Token> usedTokens = new List<Token>(); System.Diagnostics.Debug.WriteLine("Analyzing [" + s + "]"); Stack<Token> st = new Stack<Token>(); st.Push(new Token() { Type = TokenType.Q, Value = "0" }); m.Reset(s); Token linetok = null; if (m.HasNext()) linetok = m.GetNextToken(); while (linetok.Type == TokenType.DELIMITER) linetok = m.GetNextToken(); while (st.Count > 0) { //Q Token stacktok = st.Peek(); if (stacktok.Type != TokenType.Q) { System.Diagnostics.Debug.WriteLine("Unexpected token in stack"); return; } int q = Int32.Parse(stacktok.Value); String x = h.TableF.ContainsKey(linetok.Value) ? linetok.Value : linetok.Type.ToString(); if (!h.TableF.ContainsKey(x)) { System.Diagnostics.Debug.WriteLine("Unknown token " + x); return; } String command = h.TableF[x][q]; if (command.StartsWith("shift")) { st.Push(linetok); linetok = m.GetNextToken(); while (linetok.Type == TokenType.DELIMITER) linetok = m.GetNextToken(); if (linetok.Value == String.Empty) linetok.Value = "lambda"; } else if (command.StartsWith("reduce")) { int rulenum = Int32.Parse(command.Substring(6)); Rule rule = g.Rules[rulenum]; for (int r = rule.Right.Count - 1; r >= 0; r--) { st.Pop(); Token right = st.Pop(); if (!right.Value.Equals(rule.Right[r]) && !right.Type.ToString().Equals(rule.Right[r])) System.Diagnostics.Debug.WriteLine("Error while reducing according to rule " + rulenum + ": expected " + rule.Right[r] + ", got " + right); } st.Push(new Token() { Type = TokenType.NONTERM, Value = rule.Left }); //Console.WriteLine("Reduced according to rule " + rulenum); System.Diagnostics.Debug.WriteLine("--------- " + rule.Action); rules.Add(rulenum); } else if (command.StartsWith("accept")) { st.Pop(); Token start = st.Pop(); Token q0 = st.Pop(); if ((st.Count == 0) && start.Value.Equals(g.Start.Right[0]) && q0.Value.Equals("0") && (q0.Type == TokenType.Q)) { System.Diagnostics.Debug.WriteLine("ACCEPTED"); e.BuildByRules(g,rules, usedTokens); } else System.Diagnostics.Debug.WriteLine("Unexpected end of file"); return; } else { String allowed = String.Empty; foreach (var key in h.TableF.Keys) { if (h.TableF[key][q] != String.Empty) { allowed = key; break; } } throw new Exception("Error: got " + linetok.Value + " while expecting " + allowed); } //not q stacktok = st.Pop(); Token stacktok2 = st.Pop(); q = Int32.Parse(stacktok2.Value); st.Push(stacktok2); st.Push(stacktok); x = h.TableG.ContainsKey(stacktok.Value) ? stacktok.Value : stacktok.Type.ToString(); if (!h.TableG.ContainsKey(x)) { System.Diagnostics.Debug.WriteLine("Unknown token " + x); return; } if (stacktok.Type != TokenType.NONTERM) { usedTokens.Add(stacktok); System.Diagnostics.Debug.WriteLine("---PUSH " + stacktok.Value); } int gt = h.TableG[x][q]; st.Push(new Token() { Type = TokenType.Q, Value = gt.ToString() }); } }
public static Object SetGrammar(String text) { try { UserSession us = HttpContext.Current.Session["UserSession"] as UserSession; if (us == null || us.Tree == null || us.Machine == null) { throw new Exception("No lexic found"); } Grammar g = new Grammar(); g.Reset(); MagazineMachine m = new MagazineMachine(); foreach (string line in text.Split('\n').Select(l => l.Trim())) { if (string.IsNullOrEmpty(line)) continue; m.LoadRule(g, line); } g.Terminals = new HashSet<String>(g.Terminals.Except(g.NonTerminals)); g.Terminals.Add("lambda"); if (g.Rules.Count > 0) g.Start = g.Rules[0]; Helper h = new Helper(); h.CountAllQs(g); us.Helper = h; us.MagMachine = m; us.Grammar = g; return h.ToTable(); } catch (Exception e) { return ""; } }