예제 #1
0
파일: ItemLALR1.cs 프로젝트: sebgod/hime
        /// <summary>
        /// Closes this item to a set of items
        /// </summary>
        /// <param name="closure">The list to close</param>
        /// <param name="map">The current helper map</param>
        public override void CloseTo(List <Item> closure, Dictionary <Rule, Dictionary <int, List <Item> > > map)
        {
            // the item was of the form [Var -> alpha .] (reduction)
            // nothing to do
            if (Action == LRActionCode.Reduce)
            {
                return;
            }
            // Get the next symbol in the item
            Symbol next = GetNextSymbol();
            // Here the item is of the form [Var -> alpha . next beta]
            // If the next symbol is not a variable : do nothing
            // If the next symbol is a variable :
            Variable nextVar = next as Variable;

            if (nextVar == null)
            {
                return;
            }
            // Firsts is a copy of the Firsts set for beta (next choice)
            // Firsts will contains symbols that may follow Next
            // Firsts will therefore be the lookahead for child items
            TerminalSet firsts = new TerminalSet(GetNextChoice().Firsts);

            // If beta is nullifiable (contains ε) :
            if (firsts.Contains(Epsilon.Instance))
            {
                // Remove ε
                firsts.Remove(Epsilon.Instance);
                // Add the item's lookaheads
                firsts.AddRange(lookaheads);
            }
            // For each rule that has Next as a head variable :
            foreach (Rule rule in nextVar.Rules)
            {
                if (!map.ContainsKey(rule))
                {
                    map.Add(rule, new Dictionary <int, List <Item> >());
                }
                Dictionary <int, List <Item> > sub = map[rule];
                if (sub.ContainsKey(0))
                {
                    List <Item> previouses = sub[0];
                    ItemLALR1   previous   = previouses[0] as ItemLALR1;
                    previous.Lookaheads.AddRange(firsts);
                }
                else
                {
                    List <Item> items = new List <Item>();
                    sub.Add(0, items);
                    ItemLALR1 New = new ItemLALR1(rule, 0, firsts);
                    closure.Add(New);
                    items.Add(New);
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Builds the propagation table
 /// </summary>
 /// <remarks>
 /// The propagation table is a couple of list where
 /// items in the first list propagate to items in the second list at the same index
 /// </remarks>
 private void BuildPropagationTable()
 {
     for (int i = 0; i != kernels.Count; i++)
     {
         StateKernel kernelLALR1 = kernels[i];
         State       stateLR0    = graphLR0.States[i];
         // For each LALR(1) item in the kernel
         // Only the kernel needs to be examined as the other items will be discovered and treated
         // with the dummy closures
         foreach (ItemLALR1 itemLALR1 in kernelLALR1.Items)
         {
             // If ItemLALR1 is of the form [A -> alpha .]
             // => The closure will only contain the item itself
             // => Cannot be used to generate or propagate lookaheads
             if (itemLALR1.Action == LRActionCode.Reduce)
             {
                 continue;
             }
             // Item here is of the form [A -> alpha . beta]
             // Create the corresponding dummy item : [A -> alpha . beta, dummy]
             // This item is used to detect lookahead propagation
             ItemLR1     dummyItem   = new ItemLR1(itemLALR1.BaseRule, itemLALR1.DotPosition, Dummy.Instance);
             StateKernel dummyKernel = new StateKernel();
             dummyKernel.AddItem(dummyItem);
             State dummySet = dummyKernel.GetClosure();
             // For each item in the closure of the dummy item
             foreach (ItemLR1 item in dummySet.Items)
             {
                 // If the item action is a reduction
                 // => OnSymbol for this item will be created by the LALR(1) closure
                 // => Do nothing
                 if (item.Action == LRActionCode.Reduce)
                 {
                     continue;
                 }
                 // Get the child item in the child LALR(1) kernel
                 State       childLR0    = stateLR0.GetChildBy(item.GetNextSymbol());
                 StateKernel childKernel = kernels[childLR0.ID];
                 ItemLALR1   childLALR1  = (ItemLALR1)GetEquivalentInSet(childKernel, item.GetChild());
                 // If the lookaheads of the item in the dummy set contains the dummy terminal
                 if (item.Lookahead == Dummy.Instance)
                 {
                     // => Propagation from the parent item to the child
                     propagOrigins.Add(itemLALR1);
                     propagTargets.Add(childLALR1);
                 }
                 else
                 {
                     // => Spontaneous generation of lookaheads
                     childLALR1.Lookaheads.Add(item.Lookahead);
                 }
             }
         }
     }
 }
예제 #3
0
 /// <summary>
 /// Builds the kernels
 /// </summary>
 private void BuildKernels()
 {
     for (int i = 0; i != graphLR0.States.Count; i++)
     {
         State       stateLR0    = graphLR0.States[i];
         StateKernel kernelLALR1 = new StateKernel();
         foreach (Item itemLR0 in stateLR0.Kernel.Items)
         {
             ItemLALR1 itemLALR1 = new ItemLALR1(itemLR0);
             if (i == 0)
             {
                 itemLALR1.Lookaheads.Add(Epsilon.Instance);
             }
             kernelLALR1.AddItem(itemLALR1);
         }
         kernels.Add(kernelLALR1);
     }
 }
예제 #4
0
파일: ItemLALR1.cs 프로젝트: sebgod/hime
        /// <summary>
        /// Determines whether the specified <see cref="Hime.SDK.Grammars.LR.Item"/> is equal to the current <see cref="Hime.SDK.Grammars.LR.Item"/>.
        /// </summary>
        /// <param name='item'>
        /// The <see cref="Hime.SDK.Grammars.LR.Item"/> to compare with the current <see cref="Hime.SDK.Grammars.LR.Item"/>.
        /// </param>
        /// <returns>
        /// <c>true</c> if the specified <see cref="Hime.SDK.Grammars.LR.Item"/> is equal to the current
        /// <see cref="Hime.SDK.Grammars.LR.Item"/>; otherwise, <c>false</c>.
        /// </returns>
        public override bool ItemEquals(Item item)
        {
            ItemLALR1 tested = (ItemLALR1)item;

            if (!BaseEquals(tested))
            {
                return(false);
            }
            if (lookaheads.Count != tested.lookaheads.Count)
            {
                return(false);
            }
            foreach (Terminal terminal in lookaheads)
            {
                if (!tested.lookaheads.Contains(terminal))
                {
                    return(false);
                }
            }
            return(true);
        }