pat@sri-unix (06/03/82)
Reporting of syntax errors detected by yacc.
The problem is that yacc is usually not synchronized with lex. Lex
is usually a token or two ahead. There is no built-in mechanism
to save the input, so you need to do it yourself. Also, the process
is somewhat inexact: the token at which yacc calls yyerror is the
token where yacc can no longer proceed, and this is not always the
token that caused it to choose the wrong path. Nevertheless, infor-
mation can be extracted and displayed that is helpful in correcting
syntax errors. The method described below displays each line of in-
put in which an error occurred with markers for the beginning and
end of the erroneous token.
Within every lex rule is called a procedure called save,
[0-9]+ {save(yytext); etc...}
which simply appends the token to a string buffer and maintains a
pointer to the beginning of the portion just saved and another to its
end.
The routine yyerror() is a user-defined routine that is called automa-
tically when yacc detects a syntax error. My version of yyerror makes
copies of the pointers saved by save() and sets an error flag.
When end of statement is reached a routine is called that checks as to
whether the error flag is set. If so, it prints out the text of the
line with arrows underneath that correspond to the error pointers
saved earlier. The line buffer is flushed and things begin anew.
This end of statement is detected by YACC, not lex.
newline : TNEWLINE { end_line(); }
In the yacc grammar there are a number of error flushing rules a la
prog error newline { yyerrok; }
| error newline { yyerrok; }