예제 #1
0
        public void AddItem(LR0Item core)
        {
            //Check if a core had been already added. If yes, simply return
            if (!_allCores.Add(core))
            {
                return;
            }
            //Create new item, add it to AllItems, InitialItems, ReduceItems or ShiftItems
            var item = new LRItem(_state, core);

            AllItems.Add(item);

            if (item.Core.IsFinal)
            {
                ReduceItems.Add(item);
            }
            else
            {
                ShiftItems.Add(item);
            }

            if (item.Core.IsInitial)
            {
                InitialItems.Add(item);
            }

            if (core.IsFinal)
            {
                return;
            }

            //Add current term to ShiftTerms
            if (!ShiftTerms.Add(core.Current))
            {
                return;
            }

            if (core.Current is Terminal)
            {
                ShiftTerminals.Add(core.Current as Terminal);
            }

            //If current term (core.Current) is a new non-terminal, expand it
            var currNt = core.Current as NonTerminal;

            if (currNt == null)
            {
                return;
            }

            foreach (var prod in currNt.Productions)
            {
                AddItem(prod.LR0Items[0]);
            }
        }
예제 #2
0
        private Production CreateProduction(NonTerminal lvalue, BnfTermList operands)
        {
            var             prod  = new Production(lvalue);
            GrammarHintList hints = null;

            //create RValues list skipping Empty terminal and collecting grammar hints
            foreach (var operand in operands)
            {
                if (operand == _grammar.Empty)
                {
                    continue;
                }
                //Collect hints as we go - they will be added to the next non-hint element
                if (operand is GrammarHint hint)
                {
                    if (hints == null)
                    {
                        hints = new GrammarHintList();
                    }
                    hints.Add(hint);
                    continue;
                }
                //Add the operand and create LR0 Item
                prod.RValues.Add(operand);
                var lr0 = new LR0Item(_lastItemId++, prod, prod.RValues.Count - 1, hints);
                prod.LR0Items.Add(lr0);
                hints = null;
            }
            //set the flags
            if (prod.RValues.Count == 0)
            {
                prod.Flags |= ProductionFlags.IsEmpty;
            }
            //Add final LRItem
            ComputeProductionFlags(prod);
            prod.LR0Items.Add(new LR0Item(_lastItemId++, prod, prod.RValues.Count, hints));
            return(prod);
        }
예제 #3
0
 public LRItem FindByCore(LR0Item core)
 {
     return(this.FirstOrDefault(item => item.Core == core));
 }