示例#1
0
        static string ItemToString(ProductionItem item, bool doLA)
        {
            int lhsLength;
            var list    = new List <string>();
            var builder = new System.Text.StringBuilder();

            builder.AppendFormat("{0} {1}: ", item.production.num, item.production.lhs);
            lhsLength = builder.Length;

            for (int i = 0; i < item.production.rhs.Count; i++)
            {
                if (i == item.pos)
                {
                    list.Add(".");
                }
                list.Add(item.production.rhs[i].ToString());
            }

            if (item.pos == item.production.rhs.Count)
            {
                list.Add(".");
            }

            builder.Append(ListUtilities.GetStringFromList(list, " ", lhsLength + 6));

            if (item.LA != null && doLA)
            {
                builder.AppendLine();
                builder.AppendFormat("\t-lookahead: {{ {0} }}", ListUtilities.GetStringFromList(item.LA, ", ", 16));
            }

            return(builder.ToString());
        }
示例#2
0
        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();

            builder.AppendFormat("{0} {1}: ", production.num, production.lhs);


            for (int i = 0; i < production.rhs.Count; i++)
            {
                if (i == pos)
                {
                    builder.Append(". ");
                }
                builder.AppendFormat("{0} ", production.rhs[i]);
            }

            if (pos == production.rhs.Count)
            {
                builder.Append(".");
            }

            if (LA != null)
            {
                builder.AppendLine();
                builder.AppendFormat("\t-lookahead: {0}", ListUtilities.GetStringFromList(LA, ", ", 16));
            }

            return(builder.ToString());
        }
示例#3
0
        void WriteProductions(StreamWriter writer)
        {
            NonTerminal lhs = null;

            foreach (Production production in productions)
            {
                int lhsLength = production.lhs.ToString().Length;

                if (production.lhs != lhs)
                {
                    lhs = production.lhs;
                    writer.WriteLine();
                    writer.Write("{0} {1}: ", ProductionAnchor(production.num), lhs);
                }
                else
                {
                    writer.Write("{0} {1}| ", ProductionAnchor(production.num), new string(' ', lhsLength));
                }

                if (production.rhs.Count == 0)
                {
                    writer.WriteLine("/* empty */");
                }
                else
                {
                    writer.WriteLine(ListUtilities.GetStringFromList(production.rhs, " ", lhsLength + 12));
                }
            }

            writer.WriteLine();
        }
示例#4
0
        static void DiagnoseState <T>(StreamWriter writer, AutomatonState state, Mapper <T, AutomatonState> map, bool doKernel)
        {
            // List<T> statePath = ListUtilities.Map<T, AutomatonState>(state.statePath, map);
            IEnumerable <T> statePath = ListUtilities.MapC <T, AutomatonState>(state.statePath, map);

            writer.WriteLine("    Shortest prefix: {0}", ListUtilities.GetStringFromList(state.shortestPrefix, " ", 8));
            writer.WriteLine("    State path: {0}", ListUtilities.GetStringFromList(statePath, "->", 8, false));
            if (state.conflicts != null)
            {
                writer.WriteLine();
                writer.WriteLine("    <b>Conflicts in this state</b>");
                foreach (Conflict conflict in state.conflicts)
                {
                    conflict.HtmlReport(writer);
                }
            }
            if (doKernel)
            {
                writer.WriteLine("    Kernel items --");
                foreach (ProductionItem item in state.kernelItems)
                {
                    writer.WriteLine("      {0}", ItemToString(item, false));
                }
            }
            writer.WriteLine();
        }
示例#5
0
        /// <summary>
        /// This is the method that computes the shortest terminal
        /// string sequence for each NonTerminal symbol.  The immediate
        /// guide is to find those NT that are non-terminating.
        /// </summary>
        void MarkTerminating()
        {
            bool changed             = false;
            int  nonTerminatingCount = 0;

            // This uses a naive algorithm that iterates until
            // an iteration completes without changing anything.
            do
            {
                changed             = false;
                nonTerminatingCount = 0;
                foreach (KeyValuePair <string, NonTerminal> kvp in this.nonTerminals)
                {
                    NonTerminal nonTerm = kvp.Value;
                    if (!nonTerm.terminating)
                    {
                        foreach (Production prod in nonTerm.productions)
                        {
                            if (ProductionTerminates(prod))
                            {
                                nonTerm.terminating = true;
                                changed             = true;
                            }
                        }
                        if (!nonTerm.terminating)
                        {
                            nonTerminatingCount++;
                        }
                    }
                }
            } while (changed);
            //
            // Now produce some helpful diagnostics.
            // We wish to find single NonTerminals that, if made
            // terminating will fix up many, even all of the
            // non-terminating NonTerminals that have been found.
            //
            if (nonTerminatingCount > 0)
            {
                List <NonTerminal> ntDependencies = BuildDependencyGraph();
                hasNonTerminatingNonTerms = true;
                handler.AddError(
                    5,
                    String.Format(CultureInfo.InvariantCulture, "There are {0} non-terminating NonTerminal Symbols{1} {{{2}}}",
                                  nonTerminatingCount,
                                  System.Environment.NewLine,
                                  ListUtilities.GetStringFromList(ntDependencies)), null);

                FindNonTerminatingSCC(ntDependencies); // Do some diagnosis
            }
        }
        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();

            builder.AppendFormat("{0} -> ", lhs);
            if (rhs.Count == 0)
            {
                builder.Append("/* empty */");
            }
            else
            {
                builder.Append(ListUtilities.GetStringFromList(rhs, ", ", builder.Length));
            }
            return(builder.ToString());
        }
示例#7
0
 private void Walk(NonTerminal node, Stack <NonTerminal> stack, List <NonTerminal> fixes, ref int count)
 {
     count++;
     stack.Push(node);
     node.depth = count;
     foreach (NonTerminal next in node.dependsOnList)
     {
         if (next.depth == 0)
         {
             Walk(next, stack, fixes, ref count);
         }
         if (next.depth < count)
         {
             node.depth = next.depth;
         }
     }
     if (node.depth == count) // traversal leaving strongly connected component
     {
         // This algorithm is folklore. I have been using it since
         // at least early 1980s in the Gardens Point compilers.
         // I don't even remember where I learned it ... (kjg).
         //
         NonTerminal popped = stack.Pop();
         popped.depth = finishMark;
         if (popped != node)
         {
             List <NonTerminal> SCC = new List <NonTerminal>();
             SCC.Add(popped);
             do
             {
                 popped       = stack.Pop();
                 popped.depth = finishMark;
                 SCC.Add(popped);
             }while (popped != node);
             handler.AddWarning(150, String.Format(CultureInfo.InvariantCulture,
                                                   "The following {2} symbols form a non-terminating cycle {0}{{{1}}}",
                                                   System.Environment.NewLine,
                                                   ListUtilities.GetStringFromList(SCC),
                                                   SCC.Count), null);
             //
             // Check if termination of any single NonTerminal
             // would eliminate the whole cycle of dependency.
             //
             SccExperiment(SCC, fixes);
         }
     }
     count--;
 }
示例#8
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();
        }
示例#9
0
        private void LeafPropagate(NonTerminal root, List <NonTerminal> thisTestConfig)
        {
            int  count   = 0;
            bool changed = false;

            do
            {
                count   = 0;
                changed = false;
                foreach (NonTerminal nt in thisTestConfig)
                {
                    if (!nt.terminating)
                    {
                        foreach (Production prod in nt.productions)
                        {
                            if (ProductionTerminates(prod))
                            {
                                nt.terminating = true;
                                changed        = true;
                            }
                        }
                        if (!nt.terminating)
                        {
                            count++;
                        }
                    }
                }
            }while (changed);

            List <NonTerminal> filtered = FilterTerminatingElements(thisTestConfig);

            handler.AddWarning(151, String.Format(CultureInfo.InvariantCulture,
                                                  "Terminating {0} fixes the following size-{1} NonTerminal set{2}{{{3}}}",
                                                  root.ToString(),
                                                  filtered.Count,
                                                  System.Environment.NewLine,
                                                  ListUtilities.GetStringFromList(filtered)), null);
        }
示例#10
0
        void WriteProductions(StreamWriter writer)
        {
            NonTerminal lhs     = null;
            string      padding = "";

            foreach (Production production in productions)
            {
                int lhsLength = 0;
                if (production.lhs != lhs)
                {
                    if (lhs != null)   //  ==> this is a change to a new LHS, write terminating ';'
                    {
                        writer.WriteLine("{0} {1};", indexSkip, padding);
                    }
                    lhsLength = production.lhs.ToString().Length;
                    padding   = new string( ' ', lhsLength );
                    lhs       = production.lhs;
                    writer.WriteLine();
                    writer.Write("{0} {1}: ", ProductionAnchor(production.num), lhs);
                }
                else
                {
                    writer.Write("{0} {1}| ", ProductionAnchor(production.num), padding);
                }

                if (production.rhs.Count == 0)
                {
                    writer.WriteLine("/* empty */");
                }
                else
                {
                    writer.WriteLine(ListUtilities.GetStringFromList(production.rhs, " ", lhsLength + 12));
                }
            }
            writer.Write("{0} {1};", indexSkip, padding);
            writer.WriteLine();
        }