Exemplo n.º 1
0
        public override IToken RecoverInline(Parser recognizer)
        {
            // SINGLE TOKEN DELETION
            IToken matchedSymbol = SingleTokenDeletion(recognizer);

            if (matchedSymbol != null)
            {
                // we have deleted the extra token.
                // now, move past ttype token as if all were ok
                ////Console.WriteLine("2Consuming: " + recognizer.CurrentToken.Text);
                ////recognizer.Consume();
                IntervalSet expecting = recognizer.GetExpectedTokens();
                IntervalSet whatFollowsLoopIterationOrRule = expecting.Or(GetErrorRecoverySet(recognizer));
                Console.WriteLine("From Recover");
                ConsumeUntil(recognizer, whatFollowsLoopIterationOrRule);
                return(matchedSymbol);
            }
            // SINGLE TOKEN INSERTION
            if (SingleTokenInsertion(recognizer))
            {
                return(GetMissingSymbol(recognizer));
            }
            // even that didn't work; must throw the exception
            throw new InputMismatchException(recognizer);
        }
Exemplo n.º 2
0
        /// <summary>
        /// The default implementation of
        /// <see cref="IAntlrErrorStrategy.Sync(Parser)">IAntlrErrorStrategy.Sync(Parser)</see>
        /// makes sure
        /// that the current lookahead symbol is consistent with what were expecting
        /// at this point in the ATN. You can call this anytime but ANTLR only
        /// generates code to check before subrules/loops and each iteration.
        /// <p/>
        /// Implements Jim Idle's magic sync mechanism in closures and optional
        /// subrules. E.g.,
        /// <pre>
        /// a : sync ( stuff sync )* ;
        /// sync : {consume to what can follow sync} ;
        /// </pre>
        /// At the start of a sub rule upon error,
        /// <see cref="Sync(Parser)">Sync(Parser)</see>
        /// performs single
        /// token deletion, if possible. If it can't do that, it bails on the current
        /// rule and uses the default error recovery, which consumes until the
        /// resynchronization set of the current rule.
        /// <p/>
        /// If the sub rule is optional (
        /// <code>(...)?</code>
        /// ,
        /// <code>(...)*</code>
        /// , or block
        /// with an empty alternative), then the expected set includes what follows
        /// the subrule.
        /// <p/>
        /// During loop iteration, it consumes until it sees a token that can start a
        /// sub rule or what follows loop. Yes, that is pretty aggressive. We opt to
        /// stay in the loop as long as possible.
        /// <p/>
        /// <strong>ORIGINS</strong>
        /// <p/>
        /// Previous versions of ANTLR did a poor job of their recovery within loops.
        /// A single mismatch token or missing token would force the parser to bail
        /// out of the entire rules surrounding the loop. So, for rule
        /// <pre>
        /// classDef : 'class' ID '{' member* '}'
        /// </pre>
        /// input with an extra token between members would force the parser to
        /// consume until it found the next class definition rather than the next
        /// member definition of the current class.
        /// <p/>
        /// This functionality cost a little bit of effort because the parser has to
        /// compare token set at the start of the loop and at each iteration. If for
        /// some reason speed is suffering for you, you can turn off this
        /// functionality by simply overriding this method as a blank { }.
        /// </summary>
        /// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
        public virtual void Sync(Parser recognizer)
        {
            ATNState s = recognizer.Interpreter.atn.states[recognizer.State];

            //		System.err.println("sync @ "+s.stateNumber+"="+s.getClass().getSimpleName());
            // If already recovering, don't try to sync
            if (InErrorRecoveryMode(recognizer))
            {
                return;
            }
            ITokenStream tokens = ((ITokenStream)recognizer.InputStream);
            int          la     = tokens.La(1);

            // try cheaper subset first; might get lucky. seems to shave a wee bit off
            if (recognizer.Atn.NextTokens(s).Contains(la) || la == TokenConstants.Eof)
            {
                return;
            }
            // Return but don't end recovery. only do that upon valid token match
            if (recognizer.IsExpectedToken(la))
            {
                return;
            }
            switch (s.StateType)
            {
            case StateType.BlockStart:
            case StateType.StarBlockStart:
            case StateType.PlusBlockStart:
            case StateType.StarLoopEntry:
            {
                // report error and recover if possible
                if (SingleTokenDeletion(recognizer) != null)
                {
                    return;
                }
                throw new InputMismatchException(recognizer);
            }

            case StateType.PlusLoopBack:
            case StateType.StarLoopBack:
            {
                //			System.err.println("at loop back: "+s.getClass().getSimpleName());
                ReportUnwantedToken(recognizer);
                IntervalSet expecting = recognizer.GetExpectedTokens();
                IntervalSet whatFollowsLoopIterationOrRule = expecting.Or(GetErrorRecoverySet(recognizer
                                                                                              ));
                ConsumeUntil(recognizer, whatFollowsLoopIterationOrRule);
                break;
            }

            default:
            {
                // do nothing if we can't identify the exact kind of ATN state
                break;
            }
            }
        }
Exemplo n.º 3
0
        public override void Sync(Parser recognizer)
        {
            //Console.WriteLine("\t" + recognizer.CurrentToken.Text);
            ATNState s = recognizer.Interpreter.atn.states[recognizer.State];

            //		System.err.println("sync @ "+s.stateNumber+"="+s.getClass().getSimpleName());
            // If already recovering, don't try to sync
            if (InErrorRecoveryMode(recognizer))
            {
                return;
            }
            ITokenStream tokens = ((ITokenStream)recognizer.InputStream);
            int          la     = tokens.La(1);
            // try cheaper subset first; might get lucky. seems to shave a wee bit off
            var nextTokens = recognizer.Atn.NextTokens(s);

            if (nextTokens.Contains(TokenConstants.Epsilon) || nextTokens.Contains(la))
            {
                return;
            }
            switch (s.StateType)
            {
            case StateType.BlockStart:
            case StateType.StarBlockStart:
            case StateType.PlusBlockStart:
            case StateType.StarLoopEntry:                     /*{ No special treatment for the first token
                                                               * // report error and recover if possible
                                                               * if (SingleTokenDeletion(recognizer) != null) {
                                                               * return;
                                                               * }
                                                               * throw new InputMismatchException(recognizer);
                                                               * }*/

            case StateType.PlusLoopBack:
            case StateType.StarLoopBack: {
                //			System.err.println("at loop back: "+s.getClass().getSimpleName());
                //ReportUnwantedToken(recognizer);
                IntervalSet expecting = recognizer.GetExpectedTokens();
                IntervalSet whatFollowsLoopIterationOrRule = expecting.Or(GetErrorRecoverySet(recognizer));
                ConsumeUntil(recognizer, expecting);
                break;
            }

            default: {
                // do nothing if we can't identify the exact kind of ATN state
                break;
            }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// The default implementation of
        /// <see cref="IAntlrErrorStrategy.Sync(Parser)"/>
        /// makes sure
        /// that the current lookahead symbol is consistent with what were expecting
        /// at this point in the ATN. You can call this anytime but ANTLR only
        /// generates code to check before subrules/loops and each iteration.
        /// <p>Implements Jim Idle's magic sync mechanism in closures and optional
        /// subrules. E.g.,</p>
        /// <pre>
        /// a : sync ( stuff sync )* ;
        /// sync : {consume to what can follow sync} ;
        /// </pre>
        /// At the start of a sub rule upon error,
        /// <see cref="Sync(Parser)"/>
        /// performs single
        /// token deletion, if possible. If it can't do that, it bails on the current
        /// rule and uses the default error recovery, which consumes until the
        /// resynchronization set of the current rule.
        /// <p>If the sub rule is optional (
        /// <c>(...)?</c>
        /// ,
        /// <c>(...)*</c>
        /// , or block
        /// with an empty alternative), then the expected set includes what follows
        /// the subrule.</p>
        /// <p>During loop iteration, it consumes until it sees a token that can start a
        /// sub rule or what follows loop. Yes, that is pretty aggressive. We opt to
        /// stay in the loop as long as possible.</p>
        /// <p><strong>ORIGINS</strong></p>
        /// <p>Previous versions of ANTLR did a poor job of their recovery within loops.
        /// A single mismatch token or missing token would force the parser to bail
        /// out of the entire rules surrounding the loop. So, for rule</p>
        /// <pre>
        /// classDef : 'class' ID '{' member* '}'
        /// </pre>
        /// input with an extra token between members would force the parser to
        /// consume until it found the next class definition rather than the next
        /// member definition of the current class.
        /// <p>This functionality cost a little bit of effort because the parser has to
        /// compare token set at the start of the loop and at each iteration. If for
        /// some reason speed is suffering for you, you can turn off this
        /// functionality by simply overriding this method as a blank { }.</p>
        /// </summary>
        /// <exception cref="Antlr4.Runtime.RecognitionException"/>
        public virtual void Sync(Parser recognizer)
        {
            ATNState s = recognizer.Interpreter.atn.states[recognizer.State];

            //		System.err.println("sync @ "+s.stateNumber+"="+s.getClass().getSimpleName());
            // If already recovering, don't try to sync
            if (InErrorRecoveryMode(recognizer))
            {
                return;
            }
            ITokenStream tokens = ((ITokenStream)recognizer.InputStream);
            int          la     = tokens.LA(1);
            // try cheaper subset first; might get lucky. seems to shave a wee bit off
            var nextTokens = recognizer.Atn.NextTokens(s);

            if (nextTokens.Contains(la))
            {
                nextTokensContext = null;
                nextTokensState   = ATNState.InvalidStateNumber;
                return;
            }

            if (nextTokens.Contains(TokenConstants.EPSILON))
            {
                if (nextTokensContext == null)
                {
                    // It's possible the next token won't match; information tracked
                    // by sync is restricted for performance.
                    nextTokensContext = recognizer.Context;
                    nextTokensState   = recognizer.State;
                }
                return;
            }
            switch (s.StateType)
            {
            case StateType.BlockStart:
            case StateType.StarBlockStart:
            case StateType.PlusBlockStart:
            case StateType.StarLoopEntry:
            {
                // report error and recover if possible
                if (SingleTokenDeletion(recognizer) != null)
                {
                    return;
                }
                throw new InputMismatchException(recognizer);
            }

            case StateType.PlusLoopBack:
            case StateType.StarLoopBack:
            {
                //			System.err.println("at loop back: "+s.getClass().getSimpleName());
                ReportUnwantedToken(recognizer);
                IntervalSet expecting = recognizer.GetExpectedTokens();
                IntervalSet whatFollowsLoopIterationOrRule = expecting.Or(GetErrorRecoverySet(recognizer));
                ConsumeUntil(recognizer, whatFollowsLoopIterationOrRule);
                break;
            }

            default:
            {
                // do nothing if we can't identify the exact kind of ATN state
                break;
            }
            }
        }