private void CheckAndSetAlias(string alias, Terminal terminal, LexSpan span) { // // Check if this alias already known. // if (aliasTerms.ContainsKey(alias)) { // // If an alias denotes more than one logical token then used // occurrences of the literal string alias must be disallowed. // Terminal other = aliasTerms[alias]; if (other != terminal) { handler.AddWarning(153, String.Format(CultureInfo.InvariantCulture, "Alias \"{0}\" also used for previous token: {1}, used occurrences forbidden", alias, other.BaseString()), span); aliasTerms[alias] = Terminal.Ambiguous; } } else { aliasTerms[alias] = terminal; } }
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--; }
// ============================================================================= #endregion Terminating Computation // ============================================================================= internal bool CheckGrammar(ErrorHandler handler) { bool ok = true; NonTerminal nt; this.handler = handler; MarkReachable(); MarkTerminating(); foreach (KeyValuePair <string, NonTerminal> pair in nonTerminals) { nt = pair.Value; if (!nt.reached) { handler.AddWarning(152, String.Format(CultureInfo.InvariantCulture, "NonTerminal symbol \"{0}\" is unreachable", pair.Key), null); } if (nt.productions.Count == 0) { ok = false; handler.AddError(5, String.Format(CultureInfo.InvariantCulture, "NonTerminal symbol \"{0}\" has no productions", pair.Key), null); } } if (this.HasNonTerminatingNonTerms) { ok = false; } return(ok); }