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()); }
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()); }
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(); }
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(); }
/// <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()); }
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--; }
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(); }
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); }
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(); }