public static LexerEngine.Lexer Generate(string filename)
        {
            if (!filename.Contains(".miniflex"))
            {
                throw new FileLoadException("File not supported");
            }
            var lexContent = File.ReadAllLines(filename);

            try
            {
                var lexer = new LexerEngine.Lexer();
                foreach (var line in lexContent)
                {
                    var newMember = GetMember(line);
                    //Console.WriteLine("Added Token: {0} Rule {1}", newMember.Item1,@newMember.Item2);

                    lexer.AddDefinition(new TokenDefinition(newMember.Item1, new Regex(@newMember.Item2)));
                }
                return(lexer);
            }
            catch
            {
                return(null);
            }
        }
        public LR1Table(Grammar g, string miniflex)
        {
            lexer    = LexerGenerator.Generate(miniflex);
            _grammar = g; //consider building a new grammar, not just stealing the pointer (as LL1).
            _grammar.GenerateFirstAndFollow();
            _terminalLookup = new Dictionary <Symbol, int>();
            _gotoLookup     = new Dictionary <Tuple <Symbol, int>, int>();
            _lr1            = new LR1(g);


            //Get terminal symbols from grammar
            var terminals    = (_grammar.Symbols.Where(x => x.IsTerminal())).ToArray();
            var nonTerminals = (_grammar.Symbols.Where(x => x.IsNonTerminal())).ToArray();

            _acceptanceState = _lr1.AutomataStates.Keys.Count - 1;
            var maxState = _acceptanceState;

            for (var i = 0; i < terminals.Length; i++)
            {
                _terminalLookup.Add(terminals[i], i);
            }
            _terminalLookup.Add(new Symbol(Symbol.SymTypes.EOS, "$"), terminals.Length); //add the end of string symbol


            _table = new Action[_terminalLookup.Count, maxState + 1]; //generate Action lookUp table

            //Construct the table with the provided automaton
            for (var i = 0; i < maxState; i++)
            {
                var focusState = _lr1.AutomataStates[i]; //get the nth state

                //set reduce Actions
                var reduceRule = focusState.RuleToReduce;

                if (reduceRule != null)
                {
                    reduceRule.Caret = 0; //reset the caret
                    for (var j = 0; j < _grammar.ProductionRules.Count; j++)
                    {
                        if (!_grammar.ProductionRules[j].Equals(reduceRule))
                        {
                            continue;
                        }
                        foreach (var follow in g.FollowSets[focusState.Header.Header])
                        {
                            _table[_terminalLookup[follow], focusState.StateName] = new Action(ActionTypes.Reduce, j);
                        }
                        break;
                    }
                }
                //set shift Actions

                foreach (var term in _terminalLookup.Keys.Where(term => focusState.PublicTransitions.ContainsKey(term)))
                {
                    _table[_terminalLookup[term], focusState.StateName] = new Action(ActionTypes.Shift, focusState.PublicTransitions[term]);
                }

                //set goto lookup
                foreach (var nonTerm in nonTerminals.Where(nonTerm => focusState.PublicTransitions.ContainsKey(nonTerm)))
                {
                    _gotoLookup[new Tuple <Symbol, int>(nonTerm, focusState.StateName)] =
                        focusState.PublicTransitions[nonTerm];
                }
            }
        }