Error Handling
The error Token
The special token error represents a syntax error:
stmt: expr SEMICOLON
| error SEMICOLON { yyerrok; }
;
When an error occurs, the parser pops states until it can shift error, then continues parsing.
yyerror Function
The yyerror function is called on syntax errors:
C
void yyerror(const char *msg) {
fprintf(stderr, "line %d: %s\n", yylineno, msg);
}
Python
def yyerror(self, msg):
print(f"line {self.yylineno}: {msg}", file=sys.stderr)
Java
void yyerror(String msg) {
System.err.println("line " + yylineno + ": " + msg);
}
Error Recovery
yyerrok
Clears the error state, allowing normal parsing to resume:
stmt: error SEMICOLON { yyerrok; printf("Recovered at ;\n"); }
;
yyclearin
Discards the current lookahead token:
stmt: error SEMICOLON { yyerrok; yyclearin; }
;
YYERROR
Force an error from within an action:
expr: expr DIVIDE expr {
if ($3 == 0) {
yyerror("division by zero");
YYERROR;
}
$$ = $1 / $3;
}
;
YYABORT
Abort parsing immediately:
stmt: QUIT { YYABORT; }
;
YYACCEPT
Accept the input immediately:
program: statement_list END { YYACCEPT; }
;
Error Recovery Strategies
Statement-Level Recovery
Recover at statement boundaries:
program: stmt_list
;
stmt_list: stmt_list stmt
| stmt
;
stmt: valid_statement SEMICOLON
| error SEMICOLON { yyerrok; }
;
Block-Level Recovery
Recover at block boundaries:
block: LBRACE stmt_list RBRACE
| LBRACE error RBRACE { yyerrok; }
;
Parenthesis Recovery
expr: LPAREN expr RPAREN
| LPAREN error RPAREN { yyerrok; $$ = 0; }
| NUMBER
;
Error Messages
Provide context in error messages:
void yyerror(const char *msg) {
fprintf(stderr, "Error at line %d near '%s': %s\n",
yylineno, yytext, msg);
}