Esempio n. 1
0
        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);
        }
Esempio n. 2
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;
 }
Esempio n. 3
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;
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        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;
        }
Esempio n. 5
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;
 }
Esempio n. 6
0
 public void GetFirstForAll(Grammar grammar)
 {
     Firsts = new Dictionary<String, HashSet<String>>();
     Firsts.Add("lambda", new HashSet<string>() { "lambda" });
     while (OneRound(grammar)) ;
 }
Esempio n. 7
0
        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);
            }
        }
Esempio n. 8
0
        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() });
            }
        }
Esempio n. 9
0
        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 "";
            }
        }