Exemplo n.º 1
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.º 2
0
        protected override DFAState CreateDFAState(DFA dfa, ATNConfigSet configs)
        {
            int t = _input.La(1);

            if (t == AntlrV4.CaretToken.CaretTokenType && !_computingStartState)
            {
                _caretToken = (ICaretToken)_input.Lt(1);
                throw NoViableAlt(_input, _outerContext, configs, _startIndex);
            }

            return(base.CreateDFAState(dfa, configs));
        }
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;
            }
            }
        }
    public override void Recover(Parser recognizer, RecognitionException e)
    {
        // This should should move the current position to the next 'END' token
        base.Recover(recognizer, e);
        ITokenStream tokenStream = (ITokenStream)recognizer.InputStream;

        // Verify we are where we expect to be
        if (tokenStream.La(1) == MyGrammarParser.END)
        {
            // Get the next possible tokens
            IntervalSet intervalSet = GetErrorRecoverySet(recognizer);
            // Move to the next token
            tokenStream.Consume();
            // Move to the next possible token
            // If the errant element is the last in the set, this will move to the 'END' token in 'END MODULE'.
            // If there are subsequent elements in the set, this will move to the 'BEGIN' token in 'BEGIN module_element'.
            ConsumeUntil(recognizer, intervalSet);
        }
    }
Exemplo n.º 5
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
            IntervalSet nextTokens = recognizer.Atn.NextTokens(s);

            //if (nextTokens.Contains(TokenConstants.Epsilon) || nextTokens.Contains(la))
            if (nextTokens.Contains(la))
            {
                // We are sure the token matches
                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;
            }
            }
        }