Up to this point, this manual has not addressed the issue of error recovery,
i.e., how to continue parsing after the parser detects a syntax error. All
that's been handled so far is error reporting using the tt(error()) member
function with yyerror. Recall that by default tt(parse()) returns after
calling tt(error()). This means that an erroneous input line causes the
calculator program to exit. Now we show how to rectify this deficiency.

The b() language itself includes the reserved word tt(error), which may
be included in the grammar rules. In the example below it has been added as
one more alternatives for line:
        verbinsert(//LINE)(errorcalc/parser/grammar)
    This addition to the grammar allows for simple error recovery in the event
of a parse error. If an expression that cannot be evaluated is read, the error
is recognized by the third rule for line, and parsing continues (The
tt(error()) member function is still called upon to print its message as
well). Different from the implementation of tt(error) in Bison, b() proceeds
on the assumption that whenever tt(error) is used in a rule it is the grammar
constructor's intention to have the parser continue parsing. Therefore, a
statement like `tt(yyerrok;)' seen in Bison grammars is superfluous in b()
grammars. The reserved keyword tt(error) itself causes the parsing function to
skip all subsequent input until a possible token following tt(error) is
seen. In the above implementation that token would be 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. This extensive error handling is not
discussed here, as it is not specific to b() programs.

