public Boolean IsEqual(Situation nsit) { if ((nsit.Pos != Pos) || (!nsit.Term.Equals(Term)) || (!nsit.Rul.Left.Equals(Rul.Left) || (nsit.Rul.Right.Count != Rul.Right.Count))) return false; bool ret = true; for (int i = 0; i < Rul.Right.Count; i++) if (!Rul.Right[i].Equals(nsit.Rul.Right[i])) ret = false; return ret; }
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 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 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; }