Example #1
0
File: State.cs Project: sebgod/hime
 /// <summary>
 /// Initializes this state
 /// </summary>
 /// <param name="kernel">The state's kernel</param>
 /// <param name="items">The state's items</param>
 public State(StateKernel kernel, List <Item> items)
 {
     this.kernel     = kernel;
     this.items      = items;
     children        = new Dictionary <Symbol, State>(new Symbol.EqualityComparer());
     openingContexts = new Dictionary <Terminal, List <int> >();
 }
Example #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);
                 }
             }
         }
     }
 }
Example #3
0
 /// <summary>
 /// Gets the item equivalent to the specified one in the kernel
 /// </summary>
 /// <param name="kernel">A kernel</param>
 /// <param name="equivalent">An item</param>
 /// <returns>The equivalent item</returns>
 private static Item GetEquivalentInSet(StateKernel kernel, Item equivalent)
 {
     foreach (Item item in kernel.Items)
     {
         if (item.BaseEquals(equivalent))
         {
             return(item);
         }
     }
     return(null);
 }
Example #4
0
File: Graph.cs Project: sebgod/hime
 /// <summary>
 /// Determines whether the given state (as a kernel) is already in this graph
 /// </summary>
 /// <param name="kernel">A kernel</param>
 /// <returns>The corresponding state, or null if none is found</returns>
 public State ContainsState(StateKernel kernel)
 {
     foreach (State potential in states)
     {
         if (potential.Kernel.Equals(kernel))
         {
             return(potential);
         }
     }
     return(null);
 }
Example #5
0
 /// <summary>
 /// Determines whether the specified <see cref="Hime.SDK.Grammars.LR.StateKernel"/> is equal to
 /// the current <see cref="Hime.SDK.Grammars.LR.StateKernel"/>.
 /// </summary>
 /// <param name='kernel'>
 /// The <see cref="Hime.SDK.Grammars.LR.StateKernel"/> to compare with the current <see cref="Hime.SDK.Grammars.LR.StateKernel"/>.
 /// </param>
 /// <returns>
 /// <c>true</c> if the specified <see cref="Hime.SDK.Grammars.LR.StateKernel"/> is equal to the
 /// current <see cref="Hime.SDK.Grammars.LR.StateKernel"/>; otherwise, <c>false</c>.
 /// </returns>
 public bool Equals(StateKernel kernel)
 {
     if (items.Count != kernel.items.Count)
     {
         return(false);
     }
     if (dictItems.Count != kernel.dictItems.Count)
     {
         return(false);
     }
     foreach (Rule rule in dictItems.Keys)
     {
         if (!kernel.dictItems.ContainsKey(rule))
         {
             return(false);
         }
         Dictionary <int, List <Item> > left  = dictItems[rule];
         Dictionary <int, List <Item> > right = kernel.dictItems[rule];
         if (left.Count != right.Count)
         {
             return(false);
         }
         foreach (int position in left.Keys)
         {
             if (!right.ContainsKey(position))
             {
                 return(false);
             }
             List <Item> l1 = left[position];
             List <Item> l2 = right[position];
             if (l1.Count != l2.Count)
             {
                 return(false);
             }
             foreach (Item item in l1)
             {
                 if (!l2.Contains(item))
                 {
                     return(false);
                 }
             }
         }
     }
     return(true);
 }
Example #6
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);
     }
 }
Example #7
0
        /// <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);
        }
Example #8
0
File: State.cs Project: sebgod/hime
        /// <summary>
        /// Builds the given parent graph
        /// </summary>
        /// <param name="graph">The parent graph</param>
        public void BuildGraph(Graph graph)
        {
            // Shift dictionnary for the current set
            Dictionary <Symbol, StateKernel> shifts = new Dictionary <Symbol, StateKernel>();

            // Build the children kernels from the shift actions
            foreach (Item item in items)
            {
                // Ignore reduce actions
                if (item.Action == LRActionCode.Reduce)
                {
                    continue;
                }

                Symbol next = item.GetNextSymbol();
                if (shifts.ContainsKey(next))
                {
                    shifts[next].AddItem(item.GetChild());
                }
                else
                {
                    StateKernel nextKernel = new StateKernel();
                    nextKernel.AddItem(item.GetChild());
                    shifts.Add(next, nextKernel);
                }
            }
            // Close the children and add them to the graph
            foreach (Symbol next in shifts.Keys)
            {
                StateKernel nextKernel = shifts[next];
                State       child      = graph.ContainsState(nextKernel);
                if (child == null)
                {
                    child = nextKernel.GetClosure();
                    graph.Add(child);
                }
                children.Add(next, child);
            }
            // Build the context data
            foreach (Item item in items)
            {
                if (item.BaseRule.Context != 0 && item.DotPosition == 0 && item.Action == LRActionCode.Shift)
                {
                    // this is the opening of a context
                    List <Terminal> openingTerminals = new List <Terminal>();
                    Symbol          first            = item.GetNextSymbol();
                    if (first is Terminal)
                    {
                        openingTerminals.Add(first as Terminal);
                    }
                    else
                    {
                        openingTerminals.AddRange((first as Variable).Firsts);
                    }
                    foreach (Terminal terminal in openingTerminals)
                    {
                        List <int> contexts;
                        if (openingContexts.ContainsKey(terminal))
                        {
                            contexts = openingContexts[terminal];
                        }
                        else
                        {
                            contexts = new List <int>();
                            openingContexts.Add(terminal, contexts);
                        }
                        if (!contexts.Contains(item.BaseRule.Context))
                        {
                            contexts.Add(item.BaseRule.Context);
                        }
                    }
                }
            }
        }