1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
Up to this point, error-recovery hasn't yet been covered i.e., how to continue
parsing after the parser detects a syntax error. By default tt(parse) returns
after calling tt(error). This means that an erroneous input line ends the
calculator. Now we show how to recover from erroneous input.
The b() grammar-specification language includes the reserved symbol tt(error),
which can be used in production rules. In the example below it has been added
as a new alternative for recognizing the tt(line) nonterminal:
verbinsert(//LINE errorcalc/parser/grammar)
This addition to the grammar allows the calculator to recover from syntax
errors. If a syntax error is encountered, the third production rule is
activated, skipping all tokens until a newline token has been encounters. At
that point tt(line) has been recognized, and parsing continues afresh at the
next input line (the tt(error) member function is also called, printing its
message). Different from bison's tt(error) implementation, b() proceeds on the
assumption that whenever tt(error) is used in a production rule it is the
grammar constructor's intention to have the parser continue parsing
(therefore, a statement like `tt(yyerrok)', encountered in bison grammars is
superfluous in b() grammars). The reserved symbol tt(error) itself causes the
parsing function to skip all subsequent input until a token that can follow
tt(error) has been encountered. In the above implementation that token is the
newline character `tt(\n)' (see chapter ref(RECOVERY)).
This form of error recovery deals with syntax errors. There are other
kinds of errors; for example, divisions by zero, which raises an exception
signal that is normally fatal. A real calculator program must handle this
signal and use whatever it takes to discard the rest of the current line of
input and resume parsing thereafter. Handling such signals and other forms of
semantic errors is not discussed here, as it is not specific to b()
programs. But once a semantic error has been encountered, handling functions
may call tt(ERROR()), resulting in the same procedure as the one that's used
for syntax errors: all subsequenct tokens are skipped until a token has been
encountered that can follow the reserved symbol tt(error).
|