예제 #1
0
        /// <summary>
        /// Outputs an LR1 Item
        /// </summary>
        /// <param name="parser">
        /// The Parser <see cref="Parser"/>
        /// </param>
        /// <param name="lr1Item">
        /// The LR1 Item <see cref="LR1Item"/>
        /// </param>
        public static void DumpLR1Item(Parser parser, LR1Item lr1Item)
        {
            LR0Item item = parser.LR0Items[lr1Item.LR0ItemID];

            Console.Write(parser.Grammar.Tokens[parser.Productions[item.Production].Left]);
            Console.Write(" ->");
            int nPosition = 0;

            for (;;)
            {
                if (nPosition == item.Position)
                {
                    Console.Write(" *");
                }
                if (nPosition >= parser.Productions[item.Production].Right.Length)
                {
                    break;
                }
                int nToken = parser.Productions[item.Production].Right[nPosition];
                Console.Write(" " + parser.Grammar.Tokens[nToken]);

                nPosition++;
            }
            if (lr1Item.LookAhead == -1)
            {
                Console.WriteLine(", $");
            }
            else
            {
                Console.WriteLine(", " + parser.Grammar.Tokens[lr1Item.LookAhead]);
            }
        }
예제 #2
0
        public void DumpLR1Item(LR1Item lr1Item)
        {
            var item = _parser.LR0Items[lr1Item.LR0ItemID];

            _builder.Append(_parser.Grammar.SymbolNames[_parser.Productions[item.Production].Left]);
            _builder.Append(" ->");
            int nPosition = 0;

            while (true)
            {
                if (nPosition == item.Position)
                {
                    _builder.Append(" *");
                }
                if (nPosition >= _parser.Productions[item.Production].Right.Length)
                {
                    break;
                }
                int nToken = _parser.Productions[item.Production].Right[nPosition];
                _builder.Append(" ").Append(_parser.Grammar.SymbolNames[nToken]);

                nPosition++;
            }
            if (lr1Item.LookAhead == -1)
            {
                _builder.Append(", $");
            }
            else
            {
                _builder.Append(", ").Append(_parser.Grammar.SymbolNames[lr1Item.LookAhead]);
            }
            _builder.AppendLine();
        }
예제 #3
0
 /// <summary>
 /// Outputs an LR1 State
 /// </summary>
 /// <param name="parser">
 /// The Parser <see cref="Parser"/>
 /// </param>
 /// <param name="lr1State">
 /// A List of LR1 Item IDs <see cref="HashSet<System.Int32>"/>
 /// </param>
 public static void DumpLR1State(Parser parser, HashSet <int> lr1State)
 {
     foreach (int nLR1Item in lr1State)
     {
         LR1Item lr1Item = parser.LR1Items[nLR1Item];
         DumpLR1Item(parser, lr1Item);
     }
 }
예제 #4
0
        /// <summary>
        /// takes a set of LR1 Items (LR0 items with lookaheads) and produces all of those LR1 items reachable by substitution
        /// </summary>
        HashSet <int> LR1Closure(HashSet <int> i)
        {
            HashSet <int> closed = new HashSet <int>();
            List <int>    open   = new List <int>();

            foreach (int itemCopy in i)
            {
                open.Add(itemCopy);
            }

            while (open.Count > 0)
            {
                int nLR1Item = open[0];
                open.RemoveAt(0);
                LR1Item lr1Item = m_lr1Items[nLR1Item];
                LR0Item lr0Item = m_lr0Items[lr1Item.LR0ItemID];
                closed.Add(nLR1Item);

                if (lr0Item.Position < m_productions[lr0Item.Production].Right.Length)
                {
                    int nToken = m_productions[lr0Item.Production].Right[lr0Item.Position];
                    if (m_nonterminals.Contains(nToken))
                    {
                        List <int> argFirst = new List <int>();
                        for (int nIdx = lr0Item.Position + 1; nIdx < m_productions[lr0Item.Production].Right.Length; nIdx++)
                        {
                            argFirst.Add(m_productions[lr0Item.Production].Right[nIdx]);
                        }
                        HashSet <int> first       = First(argFirst, lr1Item.LookAhead);
                        int           nProduction = 0;
                        foreach (Production production in m_productions)
                        {
                            if (production.Left == nToken)
                            {
                                foreach (int nTokenFirst in first)
                                {
                                    LR0Item newLR0Item = new LR0Item {
                                        Production = nProduction, Position = 0
                                    };
                                    int     nNewLR0ItemID = GetLR0ItemID(newLR0Item);
                                    LR1Item newLR1Item    = new LR1Item {
                                        LR0ItemID = nNewLR0ItemID, LookAhead = nTokenFirst
                                    };
                                    int nNewLR1ItemID = GetLR1ItemID(newLR1Item);
                                    if (!open.Contains(nNewLR1ItemID) && !closed.Contains(nNewLR1ItemID))
                                    {
                                        open.Add(nNewLR1ItemID);
                                    }
                                }
                            }
                            nProduction++;
                        }
                    }
                }
            }

            return(closed);
        }
예제 #5
0
        /// <summary>
        /// Initializes the propogation table, and initial state of the LALR table
        /// </summary>
        void InitLALRTables()
        {
            int nLR0State = 0;

            foreach (HashSet <int> lr0State in m_lr0States)
            {
                m_lalrStates.Add(new HashSet <int>());
            }
            foreach (HashSet <int> lr0Kernel in m_lr0Kernels)
            {
                HashSet <int> J = new HashSet <int>();
                foreach (int jLR0ItemID in lr0Kernel)
                {
                    LR1Item lr1Item = new LR1Item {
                        LR0ItemID = jLR0ItemID, LookAhead = -1
                    };
                    int nLR1ItemID = GetLR1ItemID(lr1Item);
                    J.Add(nLR1ItemID);
                }
                HashSet <int> JPrime = LR1Closure(J);
                foreach (int jpLR1ItemID in JPrime)
                {
                    LR1Item lr1Item = m_lr1Items[jpLR1ItemID];
                    LR0Item lr0Item = m_lr0Items[lr1Item.LR0ItemID];

                    if ((lr1Item.LookAhead != -1) || (nLR0State == 0))
                    {
                        m_lalrStates[nLR0State].Add(jpLR1ItemID);
                    }

                    if (lr0Item.Position < m_productions[lr0Item.Production].Right.Length)
                    {
                        int     nToken       = m_productions[lr0Item.Production].Right[lr0Item.Position];
                        LR0Item lr0Successor = new LR0Item {
                            Production = lr0Item.Production, Position = lr0Item.Position + 1
                        };
                        int nLR0Successor   = GetLR0ItemID(lr0Successor);
                        int nSuccessorState = m_lrGotos[nLR0State][nToken];
                        if (lr1Item.LookAhead == -1)
                        {
                            AddPropogation(nLR0State, lr1Item.LR0ItemID, nSuccessorState, nLR0Successor);
                        }
                        else
                        {
                            LR1Item lalrItem = new LR1Item {
                                LR0ItemID = nLR0Successor, LookAhead = lr1Item.LookAhead
                            };
                            int nLALRItemID = GetLR1ItemID(lalrItem);
                            m_lalrStates[nSuccessorState].Add(nLALRItemID);
                        }
                    }
                }

                nLR0State++;
            }
        }
예제 #6
0
        /// <summary>
        /// Initializes the propogation table, and initial state of the LALR table
        /// </summary>
        int InitLALRTables()
        {
            int nLR0State = 0;

            for (var i = 0; i < _lr0States.Count; i++)
            {
                _lalrStates.Add(new HashSet <int>());
            }
            foreach (var lr0Kernel in _lr0Kernels)
            {
                var j = new HashSet <int>();
                foreach (int jLR0ItemID in lr0Kernel)
                {
                    var lr1Item    = new LR1Item(jLR0ItemID, -1);
                    int nLR1ItemID = GetLR1ItemID(lr1Item);
                    j.Add(nLR1ItemID);
                }
                var jPrime = LR1Closure(j);
                foreach (int jpLR1ItemID in jPrime)
                {
                    var lr1Item = _lr1Items[jpLR1ItemID];
                    var lr0Item = _lr0Items[lr1Item.LR0ItemID];

                    if ((lr1Item.LookAhead != -1) || (nLR0State == 0))
                    {
                        _lalrStates[nLR0State].Add(jpLR1ItemID);
                    }

                    if (lr0Item.Position < _productions[lr0Item.Production].Right.Length)
                    {
                        int nToken          = _productions[lr0Item.Production].Right[lr0Item.Position];
                        var lr0Successor    = new LR0Item(lr0Item.Production, lr0Item.Position + 1);
                        int nLR0Successor   = GetLR0ItemID(lr0Successor);
                        int nSuccessorState = _lrGotos[nLR0State][nToken];
                        if (lr1Item.LookAhead == -1)
                        {
                            AddPropogation(nLR0State, lr1Item.LR0ItemID, nSuccessorState, nLR0Successor);
                        }
                        else
                        {
                            var lalrItem    = new LR1Item(nLR0Successor, lr1Item.LookAhead);
                            int nLALRItemID = GetLR1ItemID(lalrItem);
                            _lalrStates[nSuccessorState].Add(nLALRItemID);
                        }
                    }
                }

                nLR0State++;
            }
            return(_lalrStates.Count);
        }
예제 #7
0
        /// <summary>
        /// takes a set of LR1 Items (LR0 items with lookaheads) and produces all of those LR1 items reachable by substitution
        /// </summary>
        HashSet <int> LR1Closure(IEnumerable <int> items)
        {
            var closed = new HashSet <int>();
            var open   = items.ToList();

            while (open.Count > 0)
            {
                int nLR1Item = open[0];
                open.RemoveAt(0);
                LR1Item lr1Item = _lr1Items[nLR1Item];
                LR0Item lr0Item = _lr0Items[lr1Item.LR0ItemID];
                closed.Add(nLR1Item);

                if (lr0Item.Position < _productions[lr0Item.Production].Right.Length)
                {
                    int nToken = _productions[lr0Item.Production].Right[lr0Item.Position];
                    if (_nonterminals.Contains(nToken))
                    {
                        var argFirst = new List <int>();
                        for (int nIdx = lr0Item.Position + 1; nIdx < _productions[lr0Item.Production].Right.Length; nIdx++)
                        {
                            argFirst.Add(_productions[lr0Item.Production].Right[nIdx]);
                        }
                        var first       = First(argFirst, lr1Item.LookAhead);
                        int nProduction = 0;
                        foreach (var production in _productions)
                        {
                            if (production.Left == nToken)
                            {
                                foreach (int nTokenFirst in first)
                                {
                                    var newLR0Item    = new LR0Item(nProduction, 0);
                                    int nNewLR0ItemID = GetLR0ItemID(newLR0Item);
                                    var newLR1Item    = new LR1Item(nNewLR0ItemID, nTokenFirst);
                                    int nNewLR1ItemID = GetLR1ItemID(newLR1Item);
                                    if (!open.Contains(nNewLR1ItemID) && !closed.Contains(nNewLR1ItemID))
                                    {
                                        open.Add(nNewLR1ItemID);
                                    }
                                }
                            }
                            nProduction++;
                        }
                    }
                }
            }

            return(closed);
        }
예제 #8
0
        /// <summary>
        /// Gets the ID for a particular LR1 Item
        /// </summary>
        int GetLR1ItemID(LR1Item item)
        {
            int nItemID = 0;

            foreach (LR1Item oItem in _lr1Items)
            {
                if (oItem.Equals(item))
                {
                    return(nItemID);
                }
                nItemID++;
            }
            _lr1Items.Add(item);
            return(nItemID);
        }
예제 #9
0
        /// <summary>
        /// Outputs the LALR States for the parser
        /// </summary>
        /// <param name="parser">
        /// The parser <see cref="Parser"/>
        /// </param>
        public static void DumpLALRStates(Parser parser)
        {
            int nStateID = 0;

            foreach (HashSet <int> lalrState in parser.LALRStates)
            {
                Console.WriteLine("State " + nStateID + ":");
                foreach (int nLR1Item in lalrState)
                {
                    LR1Item lr1Item = parser.LR1Items[nLR1Item];
                    DumpLR1Item(parser, lr1Item);
                }
                nStateID++;
            }
        }
예제 #10
0
        /// <summary>
        /// Calculates the states in the LALR table
        /// </summary>
        void CalculateLookAheads()
        {
            bool bChanged;

            do
            {
                bChanged = false;
                int nState = 0;
                foreach (Dictionary <int, List <LALRPropogation> > statePropogations in m_lalrPropogations)
                {
                    bool bStateChanged = false;
                    foreach (int nLR1Item in m_lalrStates[nState])
                    {
                        LR1Item lr1Item = m_lr1Items[nLR1Item];

                        if (statePropogations.ContainsKey(lr1Item.LR0ItemID))
                        {
                            foreach (LALRPropogation lalrPropogation in statePropogations[lr1Item.LR0ItemID])
                            {
                                int     nGoto = lalrPropogation.LR0TargetState;
                                LR1Item item  = new LR1Item {
                                    LR0ItemID = lalrPropogation.LR0TargetItem, LookAhead = lr1Item.LookAhead
                                };
                                if (m_lalrStates[nGoto].Add(GetLR1ItemID(item)))
                                {
                                    bChanged      = true;
                                    bStateChanged = true;
                                }
                            }
                        }
                    }

                    if (bStateChanged)
                    {
                        m_lalrStates[nState] = LR1Closure(m_lalrStates[nState]);
                    }
                    nState++;
                }
            }while(bChanged);
        }
예제 #11
0
        /// <summary>
        /// Calculates the states in the LALR table
        /// </summary>
        void CalculateLookAheads()
        {
            bool bChanged;

            do
            {
                bChanged = false;
                int nState = 0;
                foreach (var statePropogations in _lalrPropogations)
                {
                    bool bStateChanged = false;
                    foreach (int nLR1Item in _lalrStates[nState])
                    {
                        var lr1Item = _lr1Items[nLR1Item];

                        if (statePropogations.ContainsKey(lr1Item.LR0ItemID))
                        {
                            foreach (var lalrPropogation in statePropogations[lr1Item.LR0ItemID])
                            {
                                int nGoto = lalrPropogation.LR0TargetState;
                                var item  = new LR1Item(lalrPropogation.LR0TargetItem, lr1Item.LookAhead);
                                if (_lalrStates[nGoto].Add(GetLR1ItemID(item)))
                                {
                                    bChanged      = true;
                                    bStateChanged = true;
                                }
                            }
                        }
                    }

                    if (bStateChanged)
                    {
                        _lalrStates[nState] = LR1Closure(_lalrStates[nState]);
                    }
                    nState++;
                }
            }while (bChanged);
        }
예제 #12
0
        /// <summary>
        /// Generates the parse table given the lalr states, and grammar
        /// </summary>
        void GenerateParseTable()
        {
            m_parseTable         = new ParseTable();
            m_parseTable.Actions = new Action[m_lalrStates.Count, m_grammar.Tokens.Length + 1];
            for (int nStateID = 0; nStateID < m_lalrStates.Count; nStateID++)
            {
                HashSet <int> lalrState = m_lalrStates[nStateID];

                for (int nToken = -1; nToken < m_grammar.Tokens.Length; nToken++)
                {
                    List <Action> actions = new List <Action>();
                    string        sToken  = "$";
                    if (nToken >= 0)
                    {
                        sToken = m_grammar.Tokens[nToken];

                        if (m_lrGotos[nStateID][nToken] >= 0)
                        {
                            actions.Add(new Action {
                                ActionType = ActionType.Shift, ActionParameter = m_lrGotos[nStateID][nToken]
                            });
                        }
                    }

                    foreach (int nLR1ItemID in lalrState)
                    {
                        LR1Item lr1Item = m_lr1Items[nLR1ItemID];
                        LR0Item lr0Item = m_lr0Items[lr1Item.LR0ItemID];

                        if ((lr0Item.Position == m_productions[lr0Item.Production].Right.Length) && lr1Item.LookAhead == nToken)
                        {
                            Action action = new Action {
                                ActionType = ActionType.Reduce, ActionParameter = lr0Item.Production
                            };
                            if (!ListContainsAction(actions, action))
                            {
                                actions.Add(action);
                            }
                        }
                    }

                    int           nMaxPrecedence   = int.MinValue;
                    List <Action> importantActions = new List <Action>();
                    foreach (Action action in actions)
                    {
                        int nActionPrecedence = int.MinValue;
                        if (action.ActionType == ActionType.Shift)
                        {
                            nActionPrecedence = m_gotoPrecedence[nStateID][nToken];                             //nToken will never be -1
                        }
                        else if (action.ActionType == ActionType.Reduce)
                        {
                            nActionPrecedence = m_productionPrecedence[action.ActionParameter];
                        }

                        if (nActionPrecedence > nMaxPrecedence)
                        {
                            nMaxPrecedence = nActionPrecedence;
                            importantActions.Clear();
                            importantActions.Add(action);
                        }
                        else if (nActionPrecedence == nMaxPrecedence)
                        {
                            importantActions.Add(action);
                        }
                    }

                    if (importantActions.Count == 1)
                    {
                        m_parseTable.Actions[nStateID, nToken + 1] = importantActions[0];
                    }
                    else if (importantActions.Count > 1)
                    {
                        Action        shiftAction   = null;
                        List <Action> reduceActions = new List <Action>();
                        foreach (Action action in importantActions)
                        {
                            if (action.ActionType == ActionType.Reduce)
                            {
                                reduceActions.Add(action);
                            }
                            else
                            {
                                shiftAction = action;
                            }
                        }

                        Derivation derv = m_grammar.PrecedenceGroups[-nMaxPrecedence].Derivation;
                        if (derv == Derivation.LeftMost && reduceActions.Count == 1)
                        {
                            m_parseTable.Actions[nStateID, nToken + 1] = reduceActions[0];
                        }
                        else if (derv == Derivation.RightMost && shiftAction != null)
                        {
                            m_parseTable.Actions[nStateID, nToken + 1] = shiftAction;
                        }
                        else
                        {
                            if (derv == Derivation.None && reduceActions.Count == 1)
                            {
                                Debug.Console.WriteLine("Error, shift-reduce conflict in grammar");
                            }
                            else
                            {
                                Debug.Console.WriteLine("Error, reduce-reduce conflict in grammar");
                            }
                            m_parseTable.Actions[nStateID, nToken + 1] = new Action {
                                ActionType = ActionType.Error, ActionParameter = nToken
                            };
                        }
                    }
                    else
                    {
                        m_parseTable.Actions[nStateID, nToken + 1] = new Action {
                            ActionType = ActionType.Error, ActionParameter = nToken
                        };
                    }
                }
            }
        }
예제 #13
0
 public bool Equals(LR1Item item)
 {
     return((LR0ItemID == item.LR0ItemID) && (LookAhead == item.LookAhead));
 }