コード例 #1
0
 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;
     }
 }
コード例 #2
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--;
 }
コード例 #3
0
        // =============================================================================
        #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);
        }