/** <summary>Attempt to recover from a single missing or extra token.</summary> * * EXTRA TOKEN * * LA(1) is not what we are looking for. If LA(2) has the right token, * however, then assume LA(1) is some extra spurious token. Delete it * and LA(2) as if we were doing a normal match(), which advances the * input. * * MISSING TOKEN * * If current token is consistent with what could come after * ttype then it is ok to "insert" the missing token, else throw * exception For example, Input "i=(3;" is clearly missing the * ')'. When the parser returns from the nested call to expr, it * will have call chain: * * stat -> expr -> atom * * and it will be trying to match the ')' at this point in the * derivation: * * => ID '=' '(' INT ')' ('+' atom)* ';' * ^ * match() will see that ';' doesn't match ')' and report a * mismatched token error. To recover, it sees that LA(1)==';' * is in the set of tokens that can follow the ')' token * reference in rule atom. It can assume that you forgot the ')'. */ protected virtual object RecoverFromMismatchedToken(IIntStream input, int ttype, BitSet follow) { RecognitionException e = null; // if next token is what we are looking for then "delete" this token if (MismatchIsUnwantedToken(input, ttype)) { e = new UnwantedTokenException(ttype, input, TokenNames); /* * System.err.println("recoverFromMismatchedToken deleting "+ * ((TokenStream)input).LT(1)+ * " since "+((TokenStream)input).LT(2)+" is what we want"); */ BeginResync(); input.Consume(); // simply delete extra token EndResync(); ReportError(e); // report after consuming so AW sees the token in the exception // we want to return the token we're actually matching object matchedSymbol = GetCurrentInputSymbol(input); input.Consume(); // move past ttype token as if all were ok return(matchedSymbol); } // can't recover with single token deletion, try insertion if (MismatchIsMissingToken(input, follow)) { object inserted = GetMissingSymbol(input, e, ttype, follow); e = new MissingTokenException(ttype, input, inserted); ReportError(e); // report after inserting so AW sees the token in the exception return(inserted); } // even that didn't work; must throw the exception e = new MismatchedTokenException(ttype, input, TokenNames); throw e; }
public virtual string GetErrorMessage(RecognitionException e, string[] tokenNames) { string str1 = e.Message; if (e is UnwantedTokenException) { UnwantedTokenException unwantedTokenException = (UnwantedTokenException)e; string str2 = unwantedTokenException.Expecting != -1 ? tokenNames[unwantedTokenException.Expecting] : "EndOfFile"; str1 = "extraneous input " + this.GetTokenErrorDisplay(unwantedTokenException.UnexpectedToken) + " expecting " + str2; } else if (e is MissingTokenException) { MissingTokenException missingTokenException = (MissingTokenException)e; str1 = "missing " + (missingTokenException.Expecting != -1 ? tokenNames[missingTokenException.Expecting] : "EndOfFile") + " at " + this.GetTokenErrorDisplay(e.Token); } else if (e is MismatchedTokenException) { MismatchedTokenException mismatchedTokenException = (MismatchedTokenException)e; string str2 = mismatchedTokenException.Expecting != -1 ? tokenNames[mismatchedTokenException.Expecting] : "EndOfFile"; str1 = "mismatched input " + this.GetTokenErrorDisplay(e.Token) + " expecting " + str2; } else if (e is MismatchedTreeNodeException) { MismatchedTreeNodeException treeNodeException = (MismatchedTreeNodeException)e; string str2 = treeNodeException.Expecting != -1 ? tokenNames[treeNodeException.Expecting] : "EndOfFile"; str1 = "mismatched tree node: " + (treeNodeException.Node != null ? treeNodeException.Node.ToString() ?? string.Empty : string.Empty) + " expecting " + str2; } else if (e is NoViableAltException) { str1 = "no viable alternative at input " + this.GetTokenErrorDisplay(e.Token); } else if (e is EarlyExitException) { str1 = "required (...)+ loop did not match anything at input " + this.GetTokenErrorDisplay(e.Token); } else if (e is MismatchedSetException) { MismatchedSetException mismatchedSetException = (MismatchedSetException)e; str1 = "mismatched input " + this.GetTokenErrorDisplay(e.Token) + " expecting set " + (object)mismatchedSetException.Expecting; } else if (e is MismatchedNotSetException) { MismatchedNotSetException mismatchedNotSetException = (MismatchedNotSetException)e; str1 = "mismatched input " + this.GetTokenErrorDisplay(e.Token) + " expecting set " + (object)mismatchedNotSetException.Expecting; } else if (e is FailedPredicateException) { FailedPredicateException predicateException = (FailedPredicateException)e; str1 = "rule " + predicateException.RuleName + " failed predicate: {" + predicateException.PredicateText + "}?"; } return(str1); }
public virtual void Match(int c) { if (input.LA(1) != c) { if (state.backtracking > 0) { state.failed = true; return; } MismatchedTokenException mte = new MismatchedTokenException(c, input, TokenNames); Recover(mte); // don't really recover; just consume in lexer throw mte; } input.Consume(); state.failed = false; }
public virtual void Match(int c) { if (input.LA(1) != c) { if (state.backtracking > 0) { state.failed = true; return; } MismatchedTokenException mte = new MismatchedTokenException(c, input); Recover(mte); throw mte; } input.Consume(); state.failed = false; }
public override string GetErrorMessage(RecognitionException e, string[] tokenNames) { string msg = null; if (e is MismatchedTokenException) { MismatchedTokenException mte = (MismatchedTokenException)e; msg = "mismatched character " + GetCharErrorDisplay(e.Character) + " expecting " + GetCharErrorDisplay(mte.Expecting); } else if (e is NoViableAltException) { NoViableAltException nvae = (NoViableAltException)e; // for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>" // and "(decision="+nvae.decisionNumber+") and // "state "+nvae.stateNumber msg = "no viable alternative at character " + GetCharErrorDisplay(e.Character); } else if (e is EarlyExitException) { EarlyExitException eee = (EarlyExitException)e; // for development, can add "(decision="+eee.decisionNumber+")" msg = "required (...)+ loop did not match anything at character " + GetCharErrorDisplay(e.Character); } else if (e is MismatchedNotSetException) { MismatchedNotSetException mse = (MismatchedNotSetException)e; msg = "mismatched character " + GetCharErrorDisplay(e.Character) + " expecting set " + mse.Expecting; } else if (e is MismatchedSetException) { MismatchedSetException mse = (MismatchedSetException)e; msg = "mismatched character " + GetCharErrorDisplay(e.Character) + " expecting set " + mse.Expecting; } else if (e is MismatchedRangeException) { MismatchedRangeException mre = (MismatchedRangeException)e; msg = "mismatched character " + GetCharErrorDisplay(e.Character) + " expecting set " + GetCharErrorDisplay(mre.A) + ".." + GetCharErrorDisplay(mre.B); } else { msg = base.GetErrorMessage(e, tokenNames); } return(msg); }
public virtual void Match(int c) { if (this.input.LA(1) != c) { if (this.state.backtracking > 0) { this.state.failed = true; } else { MismatchedTokenException mismatchedTokenException = new MismatchedTokenException(c, (IIntStream)this.input, (IList <string>) this.TokenNames); this.Recover((RecognitionException)mismatchedTokenException); throw mismatchedTokenException; } } else { this.input.Consume(); this.state.failed = false; } }
public virtual void Match(string s) { int i = 0; while (i < s.Length) { if (input.LA(1) != s[i]) { if (state.backtracking > 0) { state.failed = true; return; } MismatchedTokenException mte = new MismatchedTokenException(s[i], input, TokenNames); Recover(mte); throw mte; } i++; input.Consume(); state.failed = false; } }
public virtual void Match(string s) { int index = 0; while (index < s.Length) { if (this.input.LA(1) != (int)s[index]) { if (this.state.backtracking > 0) { this.state.failed = true; break; } MismatchedTokenException mismatchedTokenException = new MismatchedTokenException((int)s[index], (IIntStream)this.input, (IList <string>) this.TokenNames); this.Recover((RecognitionException)mismatchedTokenException); throw mismatchedTokenException; } ++index; this.input.Consume(); this.state.failed = false; } }
public override string GetErrorMessage(RecognitionException e, string[] tokenNames) { string str; if (e is MismatchedTokenException) { MismatchedTokenException mismatchedTokenException = (MismatchedTokenException)e; str = "mismatched character " + this.GetCharErrorDisplay(e.Character) + " expecting " + this.GetCharErrorDisplay(mismatchedTokenException.Expecting); } else if (e is NoViableAltException) { str = "no viable alternative at character " + this.GetCharErrorDisplay(e.Character); } else if (e is EarlyExitException) { str = "required (...)+ loop did not match anything at character " + this.GetCharErrorDisplay(e.Character); } else if (e is MismatchedNotSetException) { MismatchedNotSetException mismatchedNotSetException = (MismatchedNotSetException)e; str = "mismatched character " + this.GetCharErrorDisplay(e.Character) + " expecting set " + (object)mismatchedNotSetException.Expecting; } else if (e is MismatchedSetException) { MismatchedSetException mismatchedSetException = (MismatchedSetException)e; str = "mismatched character " + this.GetCharErrorDisplay(e.Character) + " expecting set " + (object)mismatchedSetException.Expecting; } else if (e is MismatchedRangeException) { MismatchedRangeException mismatchedRangeException = (MismatchedRangeException)e; str = "mismatched character " + this.GetCharErrorDisplay(e.Character) + " expecting set " + this.GetCharErrorDisplay(mismatchedRangeException.A) + ".." + this.GetCharErrorDisplay(mismatchedRangeException.B); } else { str = base.GetErrorMessage(e, tokenNames); } return(str); }
private IToken MatchComment() { Match('!'); while (!(c == '!' && input.LA(2) == delimiterStopChar)) { if (c == EOF) { RecognitionException re = new MismatchedTokenException((int)'!', input); re.Line = input.Line; re.CharPositionInLine = input.CharPositionInLine; string message = string.Format("Nonterminated comment starting at {0}:{1}: '!{2}' missing", startLine, startCharPositionInLine, delimiterStopChar); errMgr.LexerError(input.SourceName, message, templateToken, re); break; } Consume(); } Consume(); Consume(); // grab !> return NewToken(COMMENT); }
/// <summary> /// What error message should be generated for the various exception types? /// /// Not very object-oriented code, but I like having all error message generation /// within one method rather than spread among all of the exception classes. This /// also makes it much easier for the exception handling because the exception /// classes do not have to have pointers back to this object to access utility /// routines and so on. Also, changing the message for an exception type would be /// difficult because you would have to subclassing exception, but then somehow get /// ANTLR to make those kinds of exception objects instead of the default. /// /// This looks weird, but trust me--it makes the most sense in terms of flexibility. /// /// For grammar debugging, you will want to override this to add more information /// such as the stack frame with GetRuleInvocationStack(e, this.GetType().Fullname) /// and, for no viable alts, the decision description and state etc... /// /// Override this to change the message generated for one or more exception types. /// </summary> public virtual string GetErrorMessage(RecognitionException e, string[] tokenNames) { string msg = e.Message; if (e is UnwantedTokenException) { UnwantedTokenException ute = (UnwantedTokenException)e; string tokenName = "<unknown>"; if (ute.Expecting == Token.EOF) { tokenName = "EOF"; } else { tokenName = tokenNames[ute.Expecting]; } msg = "extraneous input " + GetTokenErrorDisplay(ute.UnexpectedToken) + " expecting " + tokenName; } else if (e is MissingTokenException) { MissingTokenException mte = (MissingTokenException)e; string tokenName = "<unknown>"; if (mte.Expecting == Token.EOF) { tokenName = "EOF"; } else { tokenName = tokenNames[mte.Expecting]; } msg = "missing " + tokenName + " at " + GetTokenErrorDisplay(e.Token); } else if (e is MismatchedTokenException) { MismatchedTokenException mte = (MismatchedTokenException)e; string tokenName = "<unknown>"; if (mte.Expecting == Token.EOF) { tokenName = "EOF"; } else { tokenName = tokenNames[mte.Expecting]; } msg = "mismatched input " + GetTokenErrorDisplay(e.Token) + " expecting " + tokenName; } //else if (e is MismatchedTreeNodeException) //{ // MismatchedTreeNodeException mtne = (MismatchedTreeNodeException)e; // string tokenName = "<unknown>"; // if (mtne.expecting == Token.EOF) // { // tokenName = "EOF"; // } // else // { // tokenName = tokenNames[mtne.expecting]; // } // // The ternary operator is only necessary because of a bug in the .NET framework // msg = "mismatched tree node: " + ((mtne.Node!=null && mtne.Node.ToString()!=null) ? // mtne.Node : string.Empty) + " expecting " + tokenName; //} else if (e is NoViableAltException) { //NoViableAltException nvae = (NoViableAltException)e; // for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>" // and "(decision="+nvae.decisionNumber+") and // "state "+nvae.stateNumber msg = "no viable alternative at input " + GetTokenErrorDisplay(e.Token); } else if (e is EarlyExitException) { //EarlyExitException eee = (EarlyExitException)e; // for development, can add "(decision="+eee.decisionNumber+")" msg = "required (...)+ loop did not match anything at input " + GetTokenErrorDisplay(e.Token); } else if (e is MismatchedSetException) { MismatchedSetException mse = (MismatchedSetException)e; msg = "mismatched input " + GetTokenErrorDisplay(e.Token) + " expecting set " + mse.expecting; } else if (e is MismatchedNotSetException) { MismatchedNotSetException mse = (MismatchedNotSetException)e; msg = "mismatched input " + GetTokenErrorDisplay(e.Token) + " expecting set " + mse.expecting; } else if (e is FailedPredicateException) { FailedPredicateException fpe = (FailedPredicateException)e; msg = "rule " + fpe.ruleName + " failed predicate: {" + fpe.predicateText + "}?"; } return(msg); }
public virtual void Match(string s) { int num = 0; while (num < s.Length) { if (this.input.LA(1) != s[num]) { if (base.state.backtracking > 0) { base.state.failed = true; return; } MismatchedTokenException re = new MismatchedTokenException(s[num], this.input, this.TokenNames); this.Recover(re); throw re; } num++; this.input.Consume(); base.state.failed = false; } }
public virtual void Match(int c) { if (this.input.LA(1) != c) { if (base.state.backtracking > 0) { base.state.failed = true; return; } MismatchedTokenException re = new MismatchedTokenException(c, this.input, this.TokenNames); this.Recover(re); throw re; } this.input.Consume(); base.state.failed = false; }
protected virtual object RecoverFromMismatchedToken(IIntStream input, int ttype, BitSet follow) { RecognitionException e = null; if (this.MismatchIsUnwantedToken(input, ttype)) { e = new UnwantedTokenException(ttype, input, this.TokenNames); this.BeginResync(); input.Consume(); this.EndResync(); this.ReportError(e); object currentInputSymbol = this.GetCurrentInputSymbol(input); input.Consume(); return currentInputSymbol; } if (this.MismatchIsMissingToken(input, follow)) { object inserted = this.GetMissingSymbol(input, e, ttype, follow); e = new MissingTokenException(ttype, input, inserted); this.ReportError(e); return inserted; } e = new MismatchedTokenException(ttype, input, this.TokenNames); throw e; }
/** Fill a list of all NFA states visited during the parse */ protected virtual void ParseEngine( String startRule, NFAState start, NFAState stop, IIntStream input, Stack<object> ruleInvocationStack, IDebugEventListener actions, IList visitedStates ) { NFAState s = start; if ( actions != null ) { actions.EnterRule( s.nfa.grammar.FileName, start.enclosingRule.Name ); } int t = input.LA( 1 ); while ( s != stop ) { if ( visitedStates != null ) { visitedStates.Add( s ); } //Console.Out.WriteLine( "parse state " + s.stateNumber + " input=" + s.nfa.grammar.getTokenDisplayName( t ) ); // CASE 1: decision state if ( s.DecisionNumber > 0 && s.nfa.grammar.GetNumberOfAltsForDecisionNFA( s ) > 1 ) { // decision point, must predict and jump to alt DFA dfa = s.nfa.grammar.GetLookaheadDFA( s.DecisionNumber ); //if ( s.nfa.grammar.type != GrammarType.Lexer ) //{ // Console.Out.WriteLine( "decision: " + // dfa.getNFADecisionStartState().Description + // " input=" + s.nfa.grammar.getTokenDisplayName( t ) ); //} int m = input.Mark(); int predictedAlt = Predict( dfa ); if ( predictedAlt == NFA.INVALID_ALT_NUMBER ) { String description = dfa.NFADecisionStartState.Description; NoViableAltException nvae = new NoViableAltException( description, dfa.DecisionNumber, s.stateNumber, input ); if ( actions != null ) { actions.RecognitionException( nvae ); } input.Consume(); // recover throw nvae; } input.Rewind( m ); int parseAlt = s.TranslateDisplayAltToWalkAlt( predictedAlt ); //if ( s.nfa.grammar.type != GrammarType.Lexer ) //{ // Console.Out.WriteLine( "predicted alt " + predictedAlt + ", parseAlt " + parseAlt ); //} NFAState alt; if ( parseAlt > s.nfa.grammar.GetNumberOfAltsForDecisionNFA( s ) ) { // implied branch of loop etc... alt = s.nfa.grammar.nfa.GetState( s.endOfBlockStateNumber ); } else { alt = s.nfa.grammar.GetNFAStateForAltOfDecision( s, parseAlt ); } s = (NFAState)alt.transition[0].target; continue; } // CASE 2: finished matching a rule if ( s.IsAcceptState ) { // end of rule node if ( actions != null ) { actions.ExitRule( s.nfa.grammar.FileName, s.enclosingRule.Name ); } if ( ruleInvocationStack.Count == 0 ) { // done parsing. Hit the start state. //Console.Out.WriteLine( "stack empty in stop state for " + s.enclosingRule ); break; } // pop invoking state off the stack to know where to return to NFAState invokingState = (NFAState)ruleInvocationStack.Pop(); RuleClosureTransition invokingTransition = (RuleClosureTransition)invokingState.transition[0]; // move to node after state that invoked this rule s = invokingTransition.followState; continue; } Transition trans = s.transition[0]; Label label = trans.label; if ( label.IsSemanticPredicate ) { FailedPredicateException fpe = new FailedPredicateException( input, s.enclosingRule.Name, "can't deal with predicates yet" ); if ( actions != null ) { actions.RecognitionException( fpe ); } } // CASE 3: epsilon transition if ( label.IsEpsilon ) { // CASE 3a: rule invocation state if ( trans is RuleClosureTransition ) { ruleInvocationStack.Push( s ); s = (NFAState)trans.target; //Console.Out.WriteLine( "call " + s.enclosingRule.name + " from " + s.nfa.grammar.getFileName() ); if ( actions != null ) { actions.EnterRule( s.nfa.grammar.FileName, s.enclosingRule.Name ); } // could be jumping to new grammar, make sure DFA created if ( !s.nfa.grammar.AllDecisionDFAHaveBeenCreated ) { s.nfa.grammar.CreateLookaheadDFAs(); } } // CASE 3b: plain old epsilon transition, just move else { s = (NFAState)trans.target; } } // CASE 4: match label on transition else if ( label.Matches( t ) ) { if ( actions != null ) { if ( s.nfa.grammar.type == GrammarType.Parser || s.nfa.grammar.type == GrammarType.Combined ) { actions.ConsumeToken( ( (ITokenStream)input ).LT( 1 ) ); } } s = (NFAState)s.transition[0].target; input.Consume(); t = input.LA( 1 ); } // CASE 5: error condition; label is inconsistent with input else { if ( label.IsAtom ) { MismatchedTokenException mte = new MismatchedTokenException( label.Atom, input ); if ( actions != null ) { actions.RecognitionException( mte ); } input.Consume(); // recover throw mte; } else if ( label.IsSet ) { MismatchedSetException mse = new MismatchedSetException( ( (IntervalSet)label.Set ).ToRuntimeBitSet(), input ); if ( actions != null ) { actions.RecognitionException( mse ); } input.Consume(); // recover throw mse; } else if ( label.IsSemanticPredicate ) { FailedPredicateException fpe = new FailedPredicateException( input, s.enclosingRule.Name, label.SemanticContext.ToString() ); if ( actions != null ) { actions.RecognitionException( fpe ); } input.Consume(); // recover throw fpe; } else { throw new RecognitionException( input ); // unknown error } } } //Console.Out.WriteLine( "hit stop state for " + stop.enclosingRule ); if ( actions != null ) { actions.ExitRule( s.nfa.grammar.FileName, stop.enclosingRule.Name ); } }
/** <summary>What error message should be generated for the various exception types?</summary> * * <remarks> * Not very object-oriented code, but I like having all error message * generation within one method rather than spread among all of the * exception classes. This also makes it much easier for the exception * handling because the exception classes do not have to have pointers back * to this object to access utility routines and so on. Also, changing * the message for an exception type would be difficult because you * would have to subclassing exception, but then somehow get ANTLR * to make those kinds of exception objects instead of the default. * This looks weird, but trust me--it makes the most sense in terms * of flexibility. * * For grammar debugging, you will want to override this to add * more information such as the stack frame with * getRuleInvocationStack(e, this.getClass().getName()) and, * for no viable alts, the decision description and state etc... * * Override this to change the message generated for one or more * exception types. * </remarks> */ public virtual string GetErrorMessage(RecognitionException e, string[] tokenNames) { string msg = e.Message; if (e is UnwantedTokenException) { UnwantedTokenException ute = (UnwantedTokenException)e; string tokenName = "<unknown>"; if (ute.Expecting == TokenTypes.EndOfFile) { tokenName = "EndOfFile"; } else { tokenName = tokenNames[ute.Expecting]; } msg = "extraneous input " + GetTokenErrorDisplay(ute.UnexpectedToken) + " expecting " + tokenName; } else if (e is MissingTokenException) { MissingTokenException mte = (MissingTokenException)e; string tokenName = "<unknown>"; if (mte.Expecting == TokenTypes.EndOfFile) { tokenName = "EndOfFile"; } else { tokenName = tokenNames[mte.Expecting]; } msg = "missing " + tokenName + " at " + GetTokenErrorDisplay(e.Token); } else if (e is MismatchedTokenException) { MismatchedTokenException mte = (MismatchedTokenException)e; string tokenName = "<unknown>"; if (mte.Expecting == TokenTypes.EndOfFile) { tokenName = "EndOfFile"; } else { tokenName = tokenNames[mte.Expecting]; } msg = "mismatched input " + GetTokenErrorDisplay(e.Token) + " expecting " + tokenName; } else if (e is MismatchedTreeNodeException) { MismatchedTreeNodeException mtne = (MismatchedTreeNodeException)e; string tokenName = "<unknown>"; if (mtne.Expecting == TokenTypes.EndOfFile) { tokenName = "EndOfFile"; } else { tokenName = tokenNames[mtne.Expecting]; } // workaround for a .NET framework bug (NullReferenceException) string nodeText = (mtne.Node != null) ? mtne.Node.ToString() ?? string.Empty : string.Empty; msg = "mismatched tree node: " + nodeText + " expecting " + tokenName; } else if (e is NoViableAltException) { //NoViableAltException nvae = (NoViableAltException)e; // for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>" // and "(decision="+nvae.decisionNumber+") and // "state "+nvae.stateNumber msg = "no viable alternative at input " + GetTokenErrorDisplay(e.Token); } else if (e is EarlyExitException) { //EarlyExitException eee = (EarlyExitException)e; // for development, can add "(decision="+eee.decisionNumber+")" msg = "required (...)+ loop did not match anything at input " + GetTokenErrorDisplay(e.Token); } else if (e is MismatchedSetException) { MismatchedSetException mse = (MismatchedSetException)e; msg = "mismatched input " + GetTokenErrorDisplay(e.Token) + " expecting set " + mse.Expecting; } else if (e is MismatchedNotSetException) { MismatchedNotSetException mse = (MismatchedNotSetException)e; msg = "mismatched input " + GetTokenErrorDisplay(e.Token) + " expecting set " + mse.Expecting; } else if (e is FailedPredicateException) { FailedPredicateException fpe = (FailedPredicateException)e; msg = "rule " + fpe.RuleName + " failed predicate: {" + fpe.PredicateText + "}?"; } return(msg); }
/** STRING : '"' ( '\\' '"' | '\\' ~'"' | ~('\\'|'"') )* '"' ; */ private IToken MatchString() { //{setText(getText().substring(1, getText().length()-1));} bool sawEscape = false; StringBuilder buf = new StringBuilder(); buf.Append(c); Consume(); while (c != '"') { if (c == '\\') { sawEscape = true; Consume(); switch (c) { case 'n': buf.Append('\n'); break; case 'r': buf.Append('\r'); break; case 't': buf.Append('\t'); break; default: buf.Append(c); break; } Consume(); continue; } buf.Append(c); Consume(); if (c == EOF) { RecognitionException re = new MismatchedTokenException((int)'"', input); re.Line = input.Line; re.CharPositionInLine = input.CharPositionInLine; errMgr.LexerError(input.SourceName, "EOF in string", templateToken, re); break; } } buf.Append(c); Consume(); if (sawEscape) return NewToken(STRING, buf.ToString()); else return NewToken(STRING); }
/// <summary> /// Attempt to Recover from a single missing or extra token. /// </summary> /// <remarks> /// EXTRA TOKEN /// /// LA(1) is not what we are looking for. If LA(2) has the right token, /// however, then assume LA(1) is some extra spurious token. Delete it /// and LA(2) as if we were doing a normal Match(), which advances the /// input. /// /// MISSING TOKEN /// /// If current token is consistent with what could come after /// ttype then it is ok to "insert" the missing token, else throw /// exception For example, Input "i=(3;" is clearly missing the /// ')'. When the parser returns from the nested call to expr, it /// will have call chain: /// /// stat -> expr -> atom /// /// and it will be trying to Match the ')' at this point in the /// derivation: /// /// => ID '=' '(' INT ')' ('+' atom)* ';' /// ^ /// Match() will see that ';' doesn't Match ')' and report a /// mismatched token error. To Recover, it sees that LA(1)==';' /// is in the set of tokens that can follow the ')' token /// reference in rule atom. It can assume that you forgot the ')'. /// </remarks> protected internal virtual Object RecoverFromMismatchedToken(IIntStream input, int ttype, BitSet follow) { RecognitionException e = null; // if next token is what we are looking for then "delete" this token if (MismatchIsUnwantedToken(input, ttype)) { e = new UnwantedTokenException(ttype, input); BeginResync(); input.Consume(); // simply delete extra token EndResync(); ReportError(e); // report after consuming so AW sees the token in the exception // we want to return the token we're actually matching object matchedSymbol = GetCurrentInputSymbol(input); input.Consume(); // move past ttype token as if all were ok return matchedSymbol; } // can't recover with single token deletion, try insertion if (MismatchIsMissingToken(input, follow)) { object inserted = GetMissingSymbol(input, e, ttype, follow); e = new MissingTokenException(ttype, input, inserted); ReportError(e); // report after inserting so AW sees the token in the exception return inserted; } // even that didn't work; must throw the exception e = new MismatchedTokenException(ttype, input); throw e; }