/*
         * internal void DetermineLookAheadTree(LookAheadNode node)
         * {
         *  //recursion here
         *  foreach (Rule rule in Rules)
         *  {
         *      rule.DetermineLookAheadTree(node);
         *  }
         * }
         */
        internal bool DetermineFirstTerminals()
        {
            // check if nonterminal has already been visited x times
            // only determine firsts x times to allow for recursion of depth x, otherwise may wind up in endless loop
            if (visitCount > 10)
            {
                return(containsEmpty);
            }

            visitCount++;

            // reset terminals
            FirstTerminals = new Symbols();

            //recursion here

            foreach (Rule rule in Rules)
            {
                containsEmpty |= rule.DetermineFirstTerminals(FirstTerminals);
            }
            return(containsEmpty);
        }
Example #2
0
        internal bool DetermineFirstTerminals(Symbols FirstTerminals, int index)
        {
            // indicates if Nonterminal can evaluate to an empty terminal (e.g. in case T -> a? or T -> a*)
            // in which case the parent rule should continue scanning after this nonterminal for Firsts.
            bool containsEmpty = false;             // assume terminal is found

            switch (Type)
            {
            case RuleType.Terminal:
                if (Symbol == null)
                {
                    return(true);
                }

                if (!FirstTerminals.Exists(Symbol))
                {
                    FirstTerminals.Add(Symbol);
                }
                else
                {
                    Console.WriteLine("throw new Exception(\"Terminal already exists\");");
                }
                break;

            case RuleType.NonTerminal:
                if (Symbol == null)
                {
                    return(true);
                }

                NonTerminalSymbol nts = Symbol as NonTerminalSymbol;
                containsEmpty = nts.DetermineFirstTerminals();

                // add first symbols of the nonterminal if not already added
                foreach (TerminalSymbol t in nts.FirstTerminals)
                {
                    if (!FirstTerminals.Exists(t))
                    {
                        FirstTerminals.Add(t);
                    }
                    else
                    {
                        Console.WriteLine("throw new Exception(\"Terminal already exists\");");
                    }
                }
                break;

            case RuleType.Choice:
            {
                // all subrules must be evaluated to determine if they contain first terminals
                // if any subrule contains an empty, then this rule also contains an empty
                foreach (Rule r in Rules)
                {
                    containsEmpty |= r.DetermineFirstTerminals(FirstTerminals);
                }
                break;
            }

            case RuleType.OneOrMore:
            {
                // if a non-empty subrule was found, then stop further parsing.
                foreach (Rule r in Rules)
                {
                    containsEmpty = r.DetermineFirstTerminals(FirstTerminals);
                    if (!containsEmpty)                                     // found the final set of first terminals
                    {
                        break;
                    }
                }
                break;
            }

            case RuleType.Concat:
            {
                // if a non-empty subrule was found, then stop further parsing.
                // start scanning from Index

                for (int i = index; i < Rules.Count; i++)
                {
                    containsEmpty = Rules[i].DetermineFirstTerminals(FirstTerminals);
                    if (!containsEmpty)                                     // found the final set of first terminals
                    {
                        break;
                    }
                }

                // assign this concat rule to each terminal
                foreach (TerminalSymbol t in FirstTerminals)
                {
                    t.Rule = this;
                }

                break;
            }

            case RuleType.Option:
            case RuleType.ZeroOrMore:
            {
                // empty due to the nature of this rule (A? or A* can always be empty)
                containsEmpty = true;

                // if a non-empty subrule was found, then stop further parsing.
                foreach (Rule r in Rules)
                {
                    containsEmpty |= r.DetermineFirstTerminals(FirstTerminals);
                    if (!containsEmpty)                                     // found the final set of first terminals
                    {
                        break;
                    }
                }
                break;
            }

            default:
                throw new NotImplementedException();
            }
            return(containsEmpty);
        }
Example #3
0
        /*
         * internal void DetermineLookAheadTree(LookAheadNode node)
         * {
         * switch (Type)
         * {
         * case RuleType.Terminal:
         *  LookAheadNode f = node.Nodes.Find(Symbol.Name);
         *  if (f == null)
         *  {
         *      LookAheadNode n = new LookAheadNode();
         *      n.LookAheadTerminal = (TerminalSymbol) Symbol;
         *      node.Nodes.Add(n);
         *  }
         *  else
         *      Console.WriteLine("throw new Exception(\"Terminal already exists\");");
         *  break;
         * case RuleType.NonTerminal:
         *  NonTerminalSymbol nts = Symbol as NonTerminalSymbol;
         *
         *  break;
         * //case RuleType.Production:
         * case RuleType.Concat:
         *  break;
         * case RuleType.OneOrMore:
         *  break;
         * case RuleType.Option:
         * case RuleType.Choice:
         * case RuleType.ZeroOrMore:
         *  break;
         * default:
         *  throw new NotImplementedException();
         * }
         * }
         */

        internal bool DetermineFirstTerminals(Symbols FirstTerminals)
        {
            return(DetermineFirstTerminals(FirstTerminals, 0));
        }
Example #4
0
 public Grammar()
 {
     Symbols     = new Symbols();
     SkipSymbols = new Symbols();
     Directives  = new Directives();
 }