}         //method

        #endregion

        #region Creating parser states
        private void CreateInitialAndFinalStates()
        {
            //there is always just one initial production "Root' -> .Root", and we're interested in LR item at 0 index
            LR0ItemList itemList = new LR0ItemList();

            itemList.Add(Data.AugmentedRoot.Productions[0].LR0Items[0]);
            Data.InitialState = FindOrCreateState(itemList); //it is actually create
            Data.InitialState.Items[0].NewLookaheads.Add(Grammar.Eof.Key);
            #region comment about FinalState
            //Create final state - because of the way states construction works, it doesn't create the final state automatically.
            // We need to create it explicitly and assign it to _data.FinalState property
            // The final executed reduction is "Root' -> Root.". This jump is executed as follows:
            //   1. parser creates Root' node
            //   2. Parser pops the state from stack - that would be initial state
            //   3. Finally, parser tries to find the transition in state.Actions table by the key of [Root'] element.
            // We must create the final state, and create the entry in transition table
            // The final state is based on the same initial production, but different LRItem - the one with dot AFTER the root nonterminal.
            // it is item at index 1.
            #endregion
            itemList.Clear();
            itemList.Add(Data.AugmentedRoot.Productions[0].LR0Items[1]);
            Data.FinalState = FindOrCreateState(itemList); //it is actually create
            //Create shift transition from initial to final state
            Data.InitialState.Actions[Data.AugmentedRoot.Key] =
                new ActionRecord(Data.AugmentedRoot.Key, ParserActionType.Shift, Data.FinalState, null);
        }
Exemple #2
0
        private void CreateInitialAndFinalStates()
        {
            LR0ItemList itemList = new LR0ItemList();

            itemList.Add(_data.AugmentedRoot.Productions[0].LR0Items[0]);
            _data.InitialState = FindOrCreateState(itemList);
            _data.InitialState.Items[0].NewLookaheads.Add(Grammar.Eof.Key);

            itemList.Clear();
            itemList.Add(_data.AugmentedRoot.Productions[0].LR0Items[1]);

            _data.FinalState = FindOrCreateState(itemList);
            _data.InitialState.Actions[_data.AugmentedRoot.Key] =
                new ActionRecord(_data.AugmentedRoot.Key, ParserActionType.Shift, _data.FinalState, null);
        }
Exemple #3
0
        public Production(bool isInitial, NonTerminal lvalue, BnfTermList rvalues)
        {
            LValue = lvalue;

            foreach (GrammarTerm rv in rvalues)
            {
                if (rv != Grammar.Empty)
                {
                    RValues.Add(rv);
                }
            }

            foreach (GrammarTerm term in RValues)
            {
                Terminal terminal = term as Terminal;
                if (terminal == null)
                {
                    continue;
                }
                HasTerminals = true;
                if (terminal.Category == TokenCategory.Error)
                {
                    IsError = true;
                }
            }

            for (int p = 0; p <= RValues.Count; p++)
            {
                LR0Items.Add(new LR0Item(this, p));
            }
        }
        //Parser states are distinguished by the subset of kernel LR0 items.
        // So when we derive new LR0-item list by shift operation,
        // we need to find out if we have already a state with the same LR0Item list.
        // We do it by looking up in a state hash by a key - [LR0 item list key].
        // Each list's key is a concatenation of items' IDs separated by ','.
        // Before producing the key for a list, the list must be sorted;
        //   thus we garantee one-to-one correspondence between LR0Item sets and keys.
        // And of course, we count only kernel items (with dot NOT in the first position).
        #endregion
        public static string ComputeLR0ItemSetKey(LR0ItemSet items)
        {
            if (items.Count == 0)
            {
                return("");
            }
            //Copy non-initial items to separate list, and then sort it
            LR0ItemList itemList = new LR0ItemList();

            foreach (var item in items)
            {
                itemList.Add(item);
            }
            //quick shortcut
            if (itemList.Count == 1)
            {
                return(itemList[0].ID.ToString());
            }
            itemList.Sort(CompareLR0Items); //Sort by ID
            //now build the key
            StringBuilder sb = new StringBuilder(255);

            foreach (LR0Item item in itemList)
            {
                sb.Append(item.ID);
                sb.Append(",");
            }//foreach
            return(sb.ToString());
        }
Exemple #5
0
 public readonly LR0ItemList LR0Items = new LR0ItemList(); //LR0 items based on this production
 public Production(bool isInitial, NonTerminal lvalue, BnfTermList rvalues)
 {
     LValue = lvalue;
     //copy RValues skipping Empty pseudo-terminal
     foreach (BnfTerm rv in rvalues)
     {
         if (rv != Grammar.Empty)
         {
             RValues.Add(rv);
         }
     }
     //Calculate flags
     foreach (BnfTerm term in RValues)
     {
         Terminal terminal = term as Terminal;
         if (terminal == null)
         {
             continue;
         }
         HasTerminals = true;
         if (terminal.Category == TokenCategory.Error)
         {
             IsError = true;
         }
     }//foreach
     //Note that we add an extra LR0Item with p = RValues.Count
     for (int p = 0; p <= RValues.Count; p++)
     {
         LR0Items.Add(new LR0Item(this, p));
     }
 }//constructor
Exemple #6
0
        }         //method

        #endregion

        #region Creating parser states
        private void CreateParserStates()
        {
            Data.States.Clear();
            _stateHash = new ParserStateTable();
            //Create initial state
            //there is always just one initial production Root' -> Root + LF, and we're interested in LR item at 0 index
            LR0ItemList itemList = new LR0ItemList();

            itemList.Add(Data.AugmentedRoot.Productions[0].LR0Items[0]);
            Data.InitialState = FindOrCreateState(itemList); //it is actually create
            Data.InitialState.Items[0].NewLookaheads.Add(Grammar.Eof.Key);
            //create final state - we need to create it explicitly to assign to _data.FinalState property
            // final state is based on the same initial production, but different LRItem - the one with dot AFTER the root nonterminal.
            // it is item at index 1.
            itemList = new LR0ItemList();
            itemList.Add(Data.AugmentedRoot.Productions[0].LR0Items[1]);
            Data.FinalState = FindOrCreateState(itemList);

            // Iterate through states (while new ones are created) and create shift transitions and new states
            for (int index = 0; index < Data.States.Count; index++)
            {
                ParserState state = Data.States[index];
                AddClosureItems(state);
                //Get keys of all possible shifts
                ShiftTable shiftTable = GetStateShifts(state);
                //Each key in shifts dict is an input element
                // Value is LR0ItemList of shifted LR0Items for this input element.
                foreach (string input in shiftTable.Keys)
                {
                    LR0ItemList shiftedCoreItems = shiftTable[input];
                    ParserState newState         = FindOrCreateState(shiftedCoreItems);
                    state.Actions[input] = new ActionRecord(input, ParserActionType.Shift, newState, null);
                    //link original LRItems in original state to derived LRItems in newState
                    foreach (LR0Item coreItem in shiftedCoreItems)
                    {
                        LRItem fromItem = FindItem(state, coreItem.Production, coreItem.Position - 1);
                        LRItem toItem   = FindItem(newState, coreItem.Production, coreItem.Position);
                        if (!fromItem.PropagateTargets.Contains(toItem))
                        {
                            fromItem.PropagateTargets.Add(toItem);
                        }
                    } //foreach coreItem
                }     //foreach input
            }         //for index
        }             //method
Exemple #7
0
 public static string ComputeLR0ItemSetKey(LR0ItemSet items)
 {
     if (items.Count == 0) return "";
       //Copy non-initial items to separate list, and then sort it
       LR0ItemList itemList = new LR0ItemList();
       foreach (var item in items)
     itemList.Add(item);
       //quick shortcut
       if (itemList.Count == 1)
     return itemList[0].ID.ToString();
       itemList.Sort(CompareLR0Items); //Sort by ID
       //now build the key
       StringBuilder sb = new StringBuilder(255);
       foreach (LR0Item item in itemList) {
     sb.Append(item.ID);
     sb.Append(",");
       }//foreach
       return sb.ToString();
 }
    private void CreateInitialAndFinalStates()
    {
      LR0ItemList itemList = new LR0ItemList();
      itemList.Add(_data.AugmentedRoot.Productions[0].LR0Items[0]);
      _data.InitialState = FindOrCreateState(itemList);
      _data.InitialState.Items[0].NewLookaheads.Add(Grammar.Eof.Key);

      itemList.Clear();
      itemList.Add(_data.AugmentedRoot.Productions[0].LR0Items[1]);

      _data.FinalState = FindOrCreateState(itemList);
      _data.InitialState.Actions[_data.AugmentedRoot.Key] =
        new ActionRecord(_data.AugmentedRoot.Key, ParserActionType.Shift, _data.FinalState, null);
    }