Expand description
Turning a failed parse into one diagnostic a human can act on.
locate is the whole module: given the source, the AtomStream the
parse ran on and syan’s error tree, it produces one ParseFileError with
a position that names the construct the author actually got wrong.
It lives beside crate::cst::parse_file and [crate::cst_v1:: parse_file_v1] rather than inside either, because both need it and both
used to carry a private render_parse_error that was
format!("{err:?}") — a Debug dump of the whole tree, at the aggregate’s
span. Two things were wrong with that, and they are worth stating because
either alone would have looked like a small cosmetic bug:
- The span was not the failure’s.
ParseError::from_causedocuments that anAlternativesaggregate “takes the FIRST alternative’s span: with no record of how far each alternative got, that is the only deterministic choice available”. For a whole-file rule the first alternative typically dies on the first token, so the aggregate points at byte 0. - Even the right leaf can be stale. A repetition discards the failure
that ended it:
Vec<TopBinding>rolls back to the start of the binding that would not parse, and what surfaces is “expected end of input” at that binding’s start. Under 0.1 a whole library is onemodulebinding, so every error in the file reported on line 1.
The first is fixed by the standard furthest-failure rule over the tree
([best_failure]); the second only by the stream’s own high-water mark
(AtomStream::furthest), because by then the tree has forgotten. locate
uses both, and prefers the tree when the two agree on how far the parse got
— the tree’s message names the expected alternatives, which the mark cannot.
Structs§
- Parse
File Error - A parse failure, positioned at the construct that caused it.
Enums§
- Parse
Failure Kind - What kind of failure a
ParseFileErrorreports.
Functions§
- locate
- Reduce a failed parse to one position and one message.