コード例 #1
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);
                 }
             }
         }
     }
 }
コード例 #2
0
ファイル: Builder.cs プロジェクト: sebgod/hime
        /// <summary>
        /// Gets the LR(1) graph
        /// </summary>
        /// <returns>The corresponding LR(1) graph</returns>
        private Graph GetGraphLR1()
        {
            // Create the first set
            Variable    axiom  = grammar.GetVariable(Grammar.GENERATED_AXIOM);
            ItemLR1     item   = new ItemLR1(axiom.Rules[0], 0, Epsilon.Instance);
            StateKernel kernel = new StateKernel();

            kernel.AddItem(item);
            State state0 = kernel.GetClosure();
            Graph result = new Graph(state0);

            // Construct the graph
            foreach (State state in result.States)
            {
                state.BuildReductions(new StateReductionsLR1());
            }
            return(result);
        }
コード例 #3
0
        /// <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 lookahead as possible symbol for firsts
                firsts.Add(lookahead);
            }
            // 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))
                {
                    sub.Add(0, new List <Item>());
                }
                List <Item> previouses = sub[0];
                // For each symbol in Firsts : create the child with this symbol as lookahead
                foreach (Terminal first in firsts)
                {
                    // Child item creation and unique insertion
                    int  sid   = first.ID;
                    bool found = false;
                    foreach (Item previous in previouses)
                    {
                        if (previous.Lookaheads[0].ID == sid)
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        ItemLR1 New = new ItemLR1(rule, 0, first);
                        closure.Add(New);
                        previouses.Add(New);
                    }
                }
            }
        }
コード例 #4
0
        /// <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)
        {
            ItemLR1 tested = item as ItemLR1;

            return(lookahead.ID == tested.lookahead.ID && BaseEquals(tested));
        }