コード例 #1
0
        private void ComputeIncludes()
        {
            // (p,A) include (q,B) iff B -> Beta A Gamma and Gamma => empty and q -> Beta -> p

            foreach (AutomatonState q in states)
            {
                foreach (Transition qB in q.nonTerminalTransitions.Values)
                {
                    foreach (Production prod in qB.A.productions)
                    {
                        for (int i = prod.rhs.Count - 1; i >= 0; i--)
                        {
                            Symbol      A  = prod.rhs[i];
                            NonTerminal NT = A as NonTerminal;
                            if (NT != null)
                            {
                                AutomatonState p = PathTo(q, prod, i);
                                p.nonTerminalTransitions[NT].includes.Add(qB);
                            }

                            if (!A.IsNullable())
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
コード例 #2
0
        private static int GetDefaultAction(AutomatonState state)
        {
            if (state.ForceLookahead)
            {
                return(0);
            }
            IEnumerator <ParserAction> enumerator = state.parseTable.Values.GetEnumerator();

            enumerator.MoveNext();
            int defaultAction = enumerator.Current.ToNum();

            if (defaultAction > 0)
            {
                return(0); // can't have default shift action
            }
            foreach (KeyValuePair <Terminal, ParserAction> transition in state.parseTable)
            {
                if (transition.Value.ToNum() != defaultAction)
                {
                    return(0);
                }
            }

            return(defaultAction);
        }
コード例 #3
0
 internal ReduceReduceConflict(Terminal sy, string s1, string s2, int prod, AutomatonState state)
     : base(sy, s1, s2)
 {
     chosen  = prod;
     inState = state;
     state.Link(this);
 }
コード例 #4
0
 internal void AddPredecessor(AutomatonState pred)
 {
     if (predecessors == null)
     {
         predecessors = new List <AutomatonState>();
     }
     if (!predecessors.Contains(pred))
     {
         predecessors.Add(pred);
     }
 }
コード例 #5
0
        private static void GenerateShiftReduceMachineState(int stateNumber, AutomatonState state)
        {
            Console.Write("    states[{0}] = new State(", stateNumber);

            int defaultAction = GetDefaultAction(state);

            if (defaultAction != 0)
            {
                //
                //  Having a default action happens if the LR0 machine
                //  has a Reduce action, that is, no lookahead is needed.
                //
                Console.Write(defaultAction);
            }
            else
            {
                //
                //  Otherwise, we have an action that depends on the
                //  lookahead, determined by the LALR(1) automaton.
                //
                Console.Write("new int[]{");
                bool first = true;
                foreach (KeyValuePair <Terminal, ParserAction> transition in state.parseTable)
                {
                    if (!first)
                    {
                        Console.Write(",");
                    }
                    Console.Write("{0},{1}", transition.Key.num, transition.Value.ToNum());
                    first = false;
                }
                Console.Write('}');
            }
            if (state.nonTerminalTransitions.Count > 0)
            {
                //
                // The Goto table is needed if there are non-terminal transitions.
                //
                Console.Write(",new int[]{");
                bool first = true;
                foreach (Transition transition in state.nonTerminalTransitions.Values)
                {
                    if (!first)
                    {
                        Console.Write(",");
                    }
                    Console.Write("{0},{1}", transition.A.num, transition.next.num);
                    first = false;
                }
                Console.Write('}');
            }
            Console.WriteLine(");");
        }
コード例 #6
0
        static string KernelToString(AutomatonState thisState)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            builder.AppendLine();
            builder.AppendLine(Header2("Kernel Items"));
            foreach (ProductionItem item in thisState.kernelItems)
            {
                builder.AppendFormat("    {0}", ItemToString(item, true));
                builder.AppendLine();
            }
            return(builder.ToString());
        }
コード例 #7
0
        private void ExpandState(Symbol sym, AutomatonState newState)
        {
            //newState.accessedBy = sym;
            states.Add(newState);

            if (!accessedBy.ContainsKey(sym))
            {
                accessedBy[sym] = new List <AutomatonState>();
            }
            accessedBy[sym].Add(newState);

            newState.AddClosure();
            ComputeGoto(newState);
        }
コード例 #8
0
        internal void AddGoto(Symbol s, AutomatonState next)
        {
            this.Goto[s] = next;
            Terminal term;

            if ((term = s as Terminal) != null)
            {
                terminalTransitions.Add(term);
            }
            else
            {
                NonTerminal nonTerm = (NonTerminal)s;
                nonTerminalTransitions.Add(nonTerm, new Transition(nonTerm, next));
            }
        }
コード例 #9
0
        internal static void PopulatePrefixes(List <AutomatonState> states)
        {
            AutomatonState start = states[0];

            start.shortestPrefix = new List <Symbol>(); // The empty list.
            start.statePath      = new List <AutomatonState>();
            start.statePath.Add(start);

            bool changed = false;

            do
            {
                changed = false;
                foreach (AutomatonState state in states)
                {
                    List <Symbol>         newfix;
                    List <Symbol>         prefix = state.shortestPrefix;
                    List <AutomatonState> newPath;
                    List <AutomatonState> oldPath = state.statePath;

                    if (prefix != null)
                    {
                        foreach (KeyValuePair <Symbol, AutomatonState> a in state.Goto)
                        {
                            Symbol         smbl      = a.Key;
                            AutomatonState nextState = a.Value;
                            newfix  = ListClone <Symbol>(prefix);
                            newPath = ListClone <AutomatonState>(oldPath);

                            newPath.Add(nextState);
                            if (!smbl.IsNullable())
                            {
                                newfix.Add(smbl);
                            }
                            if (nextState.shortestPrefix == null ||
                                nextState.shortestPrefix.Count > newfix.Count)
                            {
                                nextState.shortestPrefix = newfix;
                                nextState.statePath      = newPath;
                                changed = true;
                            }
                        }
                    }
                }
            } while (changed);
        }
コード例 #10
0
        private static AutomatonState PathTo(AutomatonState q, Production prod, int prefix)
        {
            // q -> prod.rhs[0] ... prod.rhs[prefix] -> ???

            for (int i = 0; i < prefix; i++)
            {
                Symbol s = prod.rhs[i];
                if (q.Goto.ContainsKey(s))
                {
                    q = q.Goto[s];
                }
                else
                {
                    return(null);
                }
            }

            return(q);
        }
コード例 #11
0
        private void ComputeGoto(AutomatonState state)
        {
            foreach (ProductionItem item in state.allItems)
            {
                if (!item.expanded && !item.isReduction())
                {
                    item.expanded = true;
                    Symbol s1 = item.production.rhs[item.pos];

                    // Create itemset for new state ...
                    List <ProductionItem> itemSet = new List <ProductionItem>();
                    itemSet.Add(new ProductionItem(item.production, item.pos + 1));

                    foreach (ProductionItem item2 in state.allItems)
                    {
                        if (!item2.expanded && !item2.isReduction())
                        {
                            Symbol s2 = item2.production.rhs[item2.pos];

                            if (s1 == s2)
                            {
                                item2.expanded = true;
                                itemSet.Add(new ProductionItem(item2.production, item2.pos + 1));
                            }
                        }
                    }

                    AutomatonState existingState = FindExistingState(s1, itemSet);

                    if (existingState == null)
                    {
                        AutomatonState newState = new AutomatonState(itemSet);
                        state.AddGoto(s1, newState);
                        ExpandState(s1, newState);
                    }
                    else
                    {
                        state.AddGoto(s1, existingState);
                    }
                }
            }
        }
コード例 #12
0
        static string StateToString(AutomatonState thisState)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            //builder.AppendLine(Header2("Kernel Items"));
            //foreach (ProductionItem item in thisState.kernelItems)
            //{
            //    builder.AppendFormat("    {0}", ItemToString(item, true));
            //    builder.AppendLine();
            //}

            //builder.AppendLine();

            if (thisState.parseTable.Count > 0)
            {
                builder.AppendLine(Header2("Parser Actions"));
            }
            foreach (KeyValuePair <Terminal, ParserAction> a in thisState.parseTable)
            {
                builder.AppendFormat("    {0,-14} {1}", a.Key, ActionToString(a.Value));
                builder.AppendLine();
            }

            builder.AppendLine();

            if (thisState.nonTerminalTransitions.Count > 0)
            {
                builder.AppendLine(Header2("Transitions"));
            }
            foreach (KeyValuePair <NonTerminal, Transition> n in thisState.nonTerminalTransitions)
            {
                builder.AppendFormat("    {0,-14} go to state {1}", n.Key, StateRef(thisState.Goto[n.Key].num));
                builder.AppendLine();
            }

            builder.AppendLine();

            return(builder.ToString());
        }
コード例 #13
0
        static void DiagnoseState <T>(StreamWriter writer, AutomatonState state, Mapper <T, AutomatonState> map)
        {
            // List<T> statePath = ListUtilities.Map<T, AutomatonState>(state.statePath, map);
            IEnumerable <T> statePath = ListUtilities.MapC <T, AutomatonState>(state.statePath, map);
            IEnumerable <T> predList  = ListUtilities.MapC <T, AutomatonState>(state.predecessors, map);

            writer.WriteLine("    Shortest prefix: {0}", ListUtilities.GetStringFromList(state.shortestPrefix, " ", 8));
            writer.WriteLine("    Shortest path: {0}", ListUtilities.GetStringFromList(statePath, "->", 19, (ListUtilities.BreakRule) 16));
            writer.WriteLine("    Predecessors: {0}", ListUtilities.GetStringFromList(predList, ", ", 18, (ListUtilities.BreakRule) 16));
            writer.Write(KernelToString(state));

            if (state.conflicts != null)
            {
                writer.WriteLine();
                writer.WriteLine("    <b>Conflicts in this state</b>");
                foreach (Conflict conflict in state.conflicts)
                {
                    conflict.HtmlReport(writer);
                }
            }
            writer.WriteLine();
        }
コード例 #14
0
        internal void BuildParseTable()
        {
            foreach (AutomatonState state in states)
            {               //
                // Add shift actions ...
                // This makes shift the default action for all
                // terminal transitions. This is modified as required,
                // later in this foreach state loop.
                //
                foreach (Terminal t in state.terminalTransitions)
                {
                    state.parseTable[t] = new Shift(state.Goto[t]);
                }

                // Add reduce actions ...
                foreach (ProductionItem item in state.allItems)
                {
                    if (item.isReduction())
                    {
                        // Accept on everything
                        if (item.production == grammar.rootProduction)
                        {
                            foreach (Terminal t in grammar.terminals.Values)
                            {
                                state.parseTable[t] = new Reduce(item);
                            }
                        }

                        foreach (Terminal t in item.LA)
                        {
                            // possible conflict with existing action
                            if (state.parseTable.ContainsKey(t))
                            {
                                Reduce       reduceAction;
                                ParserAction other = state.parseTable[t];
                                Production   iProd = item.production;
                                if ((reduceAction = other as Reduce) != null)
                                {
                                    Production oProd = reduceAction.item.production;

                                    // Choose in favour of production listed first in the grammar
                                    if (oProd.num > iProd.num)
                                    {
                                        state.parseTable[t] = new Reduce(item);
                                    }

                                    string p1   = String.Format(CultureInfo.InvariantCulture, " Reduce {0}:\t{1}", oProd.num, oProd.ToString());
                                    string p2   = String.Format(CultureInfo.InvariantCulture, " Reduce {0}:\t{1}", iProd.num, iProd.ToString());
                                    int    chsn = (oProd.num > iProd.num ? iProd.num : oProd.num);
                                    grammar.conflicts.Add(new ReduceReduceConflict(t, p1, p2, chsn, state));
                                    if (GPCG.Verbose)
                                    {
                                        Console.Error.WriteLine(
                                            "Reduce/Reduce conflict in state {0} on symbol {1}",
                                            state.num,
                                            t.ToString());
                                        Console.Error.WriteLine(p1);
                                        Console.Error.WriteLine(p2);
                                    }
                                    else
                                    {
                                        Console.Error.WriteLine("Reduce/Reduce conflict, state {0}: {1} vs {2} on {3}",
                                                                state.num, iProd.num, oProd.num, t);
                                    }
                                }
                                else
                                {
                                    if (iProd.prec != null && t.prec != null)
                                    {
                                        if (iProd.prec.prec > t.prec.prec)
                                        {
                                            //
                                            //  Production iProd has precedence over t, so Reduce.
                                            //
                                            state.parseTable[t] = new Reduce(item);   // No shift/Reduce warning.
                                        }
                                        else if (iProd.prec.prec == t.prec.prec)
                                        {
                                            //
                                            //  Precedence is equal, so use associativity to decide.
                                            //
                                            if (t.prec.type == PrecType.left)
                                            {
                                                //
                                                // For %left tokens reduce the left subexpression.
                                                //
                                                state.parseTable[t] = new Reduce(item);
                                            }
                                            else if (t.prec.type == PrecType.nonassoc)   // && iProd.RightmostTerminal() == t) {
                                            // What is the correct semantics here?
                                            // If %nonassoc x y, is E x E y E an error?
                                            // The YACC spec seems to imply, but not explictly state,
                                            // that x,y are non-associative AS A GROUP
                                            // rather than just individually non-associative.
                                            //
                                            // For %nonassoc tokens disallow the shift action, and force
                                            // lookahead just in case this state has an LR0 Reduce action.
                                            //
                                            {
                                                state.parseTable.Remove(t);
                                                state.ForceLookahead = true;
                                            }
                                            // else t.prec.type == PrecType.right, so Shift.
                                        }
                                        // else iProd.prec.prec < t.proc.prec, so Shift anyway.
                                    }
                                    else    // Need to issue a Shift/Reduce warning message.
                                    {
                                        AutomatonState next = ((Shift)other).next;
                                        string         p1   = String.Format(CultureInfo.InvariantCulture, " Shift \"{0}\":\tState-{1} -> State-{2}", t, state.num, next.num);
                                        string         p2   = String.Format(CultureInfo.InvariantCulture, " Reduce {0}:\t{1}", iProd.num, iProd.ToString());
                                        grammar.conflicts.Add(new ShiftReduceConflict(t, p1, p2, state, next));
                                        if (GPCG.Verbose)
                                        {
                                            Console.Error.WriteLine("Shift/Reduce conflict");
                                            Console.Error.WriteLine(p1);
                                            Console.Error.WriteLine(p2);
                                        }
                                        else
                                        {
                                            Console.Error.WriteLine("Shift/Reduce conflict, state {0} on {1}", state.num, t);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                state.parseTable[t] = new Reduce(item);
                            }
                        }
                    }
                }
            }
        }
コード例 #15
0
 internal ShiftReduceConflict(Terminal sy, string s1, string s2, AutomatonState from, AutomatonState to)
     : base(sy, s1, s2)
 {
     fromState = from; toState = to;
     fromState.Link(this);
 }
コード例 #16
0
 internal Transition(NonTerminal A, AutomatonState next)
 {
     this.A    = A;
     this.next = next;
 }