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 SetLexic(String text)
        {
            RegExpTree tree = new RegExpTree();
            tree.Roots = new Dictionary<string, RegExpTreeItem>();
            ComplexMachine machine = new ComplexMachine(tree);

            try
            {
                foreach (string line in text.Split('\n').Select(l => l.Trim() + "#"))
                {
                    if (string.IsNullOrEmpty(line)) continue;
                    int i = 0;
                    while (line[i] != '=' && i < line.Length - 1) i++;
                    if (line[i] != '=') continue;
                    String name = line.Substring(0, i);
                    String val = line.Substring(i + 1, line.Length - i - 1);
                    tree.Roots[name] = tree.Load(val);
                }
                machine = new ComplexMachine(tree);
            }
            catch (Exception e)
            {
                return null;
            }
            UserSession us = HttpContext.Current.Session["UserSession"] as UserSession;
            if (us == null)
            {
                us = new UserSession();
                HttpContext.Current.Session.Add("UserSession", us);
            }
            us.Tree = tree;
            us.Machine = machine;

            string ret = String.Empty;
            foreach (var m in machine.Machines.Keys)
                ret = ret + "<br/>" + machine.Machines[m].ToTable(m);
            return ret;
        }