Happy supports a limited form of error
recovery, using the special symbol error
in a grammar
file. When Happy finds a parse error during
parsing, it automatically inserts the error
symbol; if
your grammar deals with error
explicitly, then it can
detect the error and carry on.
For example, the Happy grammar for Haskell uses error recovery to implement Haskell layout. The grammar has a rule that looks like this:
close : '}' { () } | error { () }
This says that a close brace in a layout-indented context may be either a curly brace (inserted by the lexical analyser), or a parse error.
This rule is used to parse expressions like let x
= e in e'
: the layout system inserts an open brace before
x
, and the occurrence of the in
symbol
generates a parse error, which is interpreted as a close brace
by the above rule.
Note for yacc
users: this form of error recovery
is strictly more limited than that provided by yacc
.
During a parse error condition, yacc
attempts to
discard states and tokens in order to get back into a state
where parsing may continue; Happy doesn't do this.
The reason is that normal yacc
error recovery is
notoriously hard to describe, and the semantics depend heavily
on the workings of a shift-reduce parser. Furthermore,
different implementations of yacc
appear to implement
error recovery differently. Happy's limited error
recovery on the other hand is well-defined, as is just
sufficient to implement the Haskell layout rule (which is why it
was added in the first place).