Пример #1
0
        public LookaheadSet Look(NFAState s)
        {
            if (NFAToDFAConverter.debug)
            {
                Console.Out.WriteLine("> LOOK(" + s + ")");
            }
            _lookBusy.Clear();
            LookaheadSet look = FirstCore(s, true);

            // FOLLOW makes no sense (at the moment!) for lexical rules.
            if (_grammar.type != GrammarType.Lexer && look.Member(Label.EOR_TOKEN_TYPE))
            {
                // avoid altering FIRST reset as it is cached
                LookaheadSet f = Follow(s.enclosingRule);
                f.OrInPlace(look);
                f.Remove(Label.EOR_TOKEN_TYPE);
                look = f;
                //look.orInPlace(FOLLOW(s.enclosingRule));
            }
            else if (_grammar.type == GrammarType.Lexer && look.Member(Label.EOT))
            {
                // if this has EOT, lookahead is all char (all char can follow rule)
                //look = new LookaheadSet(Label.EOT);
                look = new LookaheadSet(IntervalSet.COMPLETE_SET);
            }
            if (NFAToDFAConverter.debug)
            {
                Console.Out.WriteLine("< LOOK(" + s + ")=" + look.ToString(_grammar));
            }
            return(look);
        }
Пример #2
0
        protected virtual LookaheadSet FirstCore(NFAState s, bool chaseFollowTransitions)
        {
            /*
             * [email protected]("_LOOK("+s+") in rule "+s.enclosingRule);
             * if ( s.transition[0] instanceof RuleClosureTransition ) {
             *  [email protected]("go to rule "+((NFAState)s.transition[0].target).enclosingRule);
             * }
             */
            if (!chaseFollowTransitions && s.IsAcceptState)
            {
                if (_grammar.type == GrammarType.Lexer)
                {
                    // FOLLOW makes no sense (at the moment!) for lexical rules.
                    // assume all char can follow
                    return(new LookaheadSet(IntervalSet.COMPLETE_SET));
                }
                return(new LookaheadSet(Label.EOR_TOKEN_TYPE));
            }

            if (_lookBusy.Contains(s))
            {
                // return a copy of an empty set; we may modify set inline
                return(new LookaheadSet());
            }
            _lookBusy.Add(s);

            Transition transition0 = s.transition[0];

            if (transition0 == null)
            {
                return(null);
            }

            if (transition0.label.IsAtom)
            {
                int atom = transition0.label.Atom;
                return(new LookaheadSet(atom));
            }
            if (transition0.label.IsSet)
            {
                IIntSet sl = transition0.label.Set;
                return(new LookaheadSet(sl));
            }

            // compute FIRST of transition 0
            LookaheadSet tset = null;

            // if transition 0 is a rule call and we don't want FOLLOW, check cache
            if (!chaseFollowTransitions && transition0 is RuleClosureTransition)
            {
                LookaheadSet prev = _firstCache.get((NFAState)transition0.target);
                if (prev != null)
                {
                    tset = new LookaheadSet(prev);
                }
            }

            // if not in cache, must compute
            if (tset == null)
            {
                tset = FirstCore((NFAState)transition0.target, chaseFollowTransitions);
                // save FIRST cache for transition 0 if rule call
                if (!chaseFollowTransitions && transition0 is RuleClosureTransition)
                {
                    _firstCache[(NFAState)transition0.target] = tset;
                }
            }

            // did we fall off the end?
            if (_grammar.type != GrammarType.Lexer && tset.Member(Label.EOR_TOKEN_TYPE))
            {
                if (transition0 is RuleClosureTransition)
                {
                    // we called a rule that found the end of the rule.
                    // That means the rule is nullable and we need to
                    // keep looking at what follows the rule ref.  E.g.,
                    // a : b A ; where b is nullable means that LOOK(a)
                    // should include A.
                    RuleClosureTransition ruleInvocationTrans =
                        (RuleClosureTransition)transition0;
                    // remove the EOR and get what follows
                    //tset.remove(Label.EOR_TOKEN_TYPE);
                    NFAState     following = (NFAState)ruleInvocationTrans.followState;
                    LookaheadSet fset      = FirstCore(following, chaseFollowTransitions);
                    fset.OrInPlace(tset);   // tset cached; or into new set
                    fset.Remove(Label.EOR_TOKEN_TYPE);
                    tset = fset;
                }
            }

            Transition transition1 = s.transition[1];

            if (transition1 != null)
            {
                LookaheadSet tset1 =
                    FirstCore((NFAState)transition1.target, chaseFollowTransitions);
                tset1.OrInPlace(tset);   // tset cached; or into new set
                tset = tset1;
            }

            return(tset);
        }