예제 #1
0
 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;
 }
예제 #2
0
        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;
                        }
                    }
                }
            }
        }
예제 #3
0
 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;
 }
예제 #4
0
 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;
 }