Error reporting presents diagnostic information when a computation fails: where failure occurred, what caused it, and what larger operation was underway. In parser combinators, grammar definitions alone do not determine these messages, so reporting must be designed explicitly rather than added as an arbitrary implementation detail. section 9.5 section 9.1
Useful parser error reporting answers several design questions:
- Identifies the precise input location and immediate cause, such as an unexpected uppercase character where lowercase 'a' was expected. section 9.5 section 9.5.2
- Lets programmers choose meaningful labels instead of exposing only low-level expectations or generic failure messages. section 9.5 section 9.5.2
- Preserves nested context when a small parser fails inside larger operations, such as a second magic word inside a magic spell. section 9.5.2
- Makes alternatives deliberate by deciding whether to try another parser and whether to report one failure or several. section 9.5
Nested parser context
For a parser combining string("abra"), optional spaces, and string("cadabra"), input "abra cAdabra" fails at the uppercase "A". Reporting only the expected lowercase character pinpoints the immediate cause; labeling the final parser "second magic word" and enclosing it in a higher-level scope can also explain what the parser was doing. A ParseError stack stores these messages as (Location, String) pairs, with the newest scope at the head. section 9.5.2
case class ParseError(stack: List[(Location, String)])
Inspect the ParseError representation together with run and scope to see how parser failures become structured, nestable data. section 9.5.2
