|
|
Another form of error rule can be used in interactive applications where it may be desirable to permit a line to be reentered after an error. The following example illustrates one way to do this:
input : error ´\n´ { (void) printf( "Reenter last line: " ); } input { $$ = $4; } ;There is one potential difficulty with this approach: the parser must correctly process three input tokens before it considers that it has correctly resynchronized after the error. If the reentered line contains an error in the first two tokens, the parser deletes the offending tokens and gives no message. This is unlikely to be acceptable, and so there is a mechanism that can force the parser to believe that error recovery has been accomplished. The following statement in an action resets the parser to its normal mode:
yyerrok ;The last example can be rewritten as follows:
input: error ´\n´ { yyerrok; (void) printf( "Reenter last line: " ); } input { $$ = $4; } ;As previously mentioned, the next token seen after the error symbol is the same token that was seen when error was discovered. Sometimes this is inappropriate: for example, an error recovery action might take upon itself the job of finding the correct place to resume input. In this case, the previous look-ahead token must be cleared. This can be done with the statement:
yyclearin ;For example, suppose that the action after error is to call some sophisticated resynchronization routine that attempts to advance the input to the beginning of the next valid statement. After this routine is called, the next token returned by the lexical analyzer is presumably the first token in a legal statement. The old illegal token must be discarded and the error state reset. An action similar to the following can perform this:
stat : error { resynch(); yyerrok ; yyclearin; } ;