Yacc Error Messages

A nice compiler gives the user meaningful error messages. For example, not much information is conveyed by the following message:

syntax error

If we track the line number in lex then we can at least give the user a line number:

void yyerror(char *s) {
    fprintf(stderr, "line %d: %s\n", yylineno, s);
}

When yacc discovers a parsing error the default action is to call yyerror and then return from yylex with a return value of one. A more graceful action flushes the input stream to a statement delimiter and continues to scan:

stmt:
         ';'
        | expr ';'
        | PRINT expr ';'
        | VARIABLE '=' expr ';
        | WHILE '(' expr ')' stmt    
        | IF '(' expr ')' stmt %prec IFX
        | IF '(' expr ')' stmt ELSE stmt
        | '{' stmt_list '}'
        | error ';'
        | error '}'
        ;

The error token is a special feature of yacc that will match all input until the token following error is found. For this example, when yacc detects an error in a statement it will call yyerror, flush input up to the next semicolon or brace, and resume scanning.