Ejemplo n.º 1
0
        private TransitionTable(int tokenCount, int stateCount, int productionCount, string[] tokenDescriptions)
        {
            TokenCount      = tokenCount;
            StateCount      = stateCount;
            ProductionCount = productionCount;

            m_gotoTable         = new int[stateCount, productionCount];
            m_shiftTable        = new ActionListNode <int> [stateCount, tokenCount + 1];
            m_reduceTable       = new ActionListNode <int> [stateCount, tokenCount + 1];
            m_tokenDescriptions = tokenDescriptions;
        }
Ejemplo n.º 2
0
        public IEnumerator <T> GetEnumerator()
        {
            ActionListNode <T> currentNode = this;

            do
            {
                yield return(currentNode.Value);

                currentNode = currentNode.m_nextNode;
            } while (currentNode != null);
        }
Ejemplo n.º 3
0
        internal static void AppendToLast(ref ActionListNode <T> list, T value)
        {
            if (list == null)
            {
                list = new ActionListNode <T>(value);
            }
            else
            {
                ActionListNode <T> head = list;

                while (head.m_nextNode != null)
                {
                    head = head.m_nextNode;
                }

                head.Append(new ActionListNode <T>(value));
            }
        }
Ejemplo n.º 4
0
        public ActionListNode <T> Append(ActionListNode <T> next)
        {
            m_nextNode = next;

            return(m_nextNode);
        }
Ejemplo n.º 5
0
        public static TransitionTable Create(LR0Model model, ScannerInfo scannerInfo)
        {
            CodeContract.RequiresArgumentNotNull(model, "model");


            string[]           tokenDescriptions = new string[scannerInfo.EndOfStreamTokenIndex + 1];
            List <IProduction> nonterminals      = new List <IProduction>();

            foreach (var production in model.ProductionInfoManager.Productions)
            {
                if (!production.IsTerminal)
                {
                    var info = model.ProductionInfoManager.GetInfo(production);

                    info.NonTerminalIndex = nonterminals.Count;
                    nonterminals.Add(production);
                }
                else
                {
                    var terminal = (production as Terminal);

                    string description;
                    int    index;

                    if (terminal != null)
                    {
                        index       = terminal.Token.Index;
                        description = terminal.Token.Description;
                    }
                    else
                    {
                        index       = scannerInfo.EndOfStreamTokenIndex;
                        description = "$";
                    }

                    tokenDescriptions[index] = description;
                }
            }

            //add one null reference to non-terminal list
            //for "accept" action in parsing
            nonterminals.Add(null);

            TransitionTable table = new TransitionTable(scannerInfo.EndOfStreamTokenIndex + 1, model.States.Count, nonterminals.Count, tokenDescriptions);

            table.m_nonTerminals          = nonterminals.ToArray();
            table.m_acceptProductionIndex = nonterminals.Count - 1;

            for (int i = 0; i < model.States.Count; i++)
            {
                var state = model.States[i];

                foreach (var edge in state.Edges)
                {
                    var edgeSymbol = model.ProductionInfoManager.Productions[edge.SymbolIndex];
                    var info       = model.ProductionInfoManager.GetInfo(edgeSymbol);

                    if (edgeSymbol.IsTerminal)
                    {
                        //shift
                        Terminal t          = edgeSymbol as Terminal;
                        int      tokenIndex = t == null ? scannerInfo.EndOfStreamTokenIndex : t.Token.Index;



                        ActionListNode <int> .AppendToLast(ref table.m_shiftTable[i, tokenIndex], edge.TargetStateIndex);
                    }
                    else
                    {
                        //goto
                        table.m_gotoTable[i, info.NonTerminalIndex] = edge.TargetStateIndex;
                    }
                }

                //lexer states for shifting
                if (state.MaxShiftingLexer != null)
                {
                    ActionListNode <int> .AppendToLast(ref table.m_shiftTable[i, table.TokenCount], state.MaxShiftingLexer.Value);
                }

                //reduces
                foreach (var reduce in state.Reduces)
                {
                    Terminal t          = reduce.ReduceTerminal as Terminal;
                    int      tokenIndex = t == null ? scannerInfo.EndOfStreamTokenIndex : t.Token.Index;

                    var info = model.ProductionInfoManager.GetInfo(reduce.ReduceProduction);

                    ActionListNode <int> .AppendToLast(ref table.m_reduceTable[i, tokenIndex], info.NonTerminalIndex);
                }

                //lexer states for reducing
                if (state.MaxReducingLexer != null)
                {
                    ActionListNode <int> .AppendToLast(ref table.m_reduceTable[i, table.TokenCount], state.MaxReducingLexer.Value);
                }

                //accepts
                if (state.IsAcceptState)
                {
                    ActionListNode <int> .AppendToLast(ref table.m_reduceTable[i, scannerInfo.EndOfStreamTokenIndex], table.m_acceptProductionIndex);
                }
            }

            return(table);
        }