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( 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; }
/** <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; }