Error Recovery โ
What you'll learn โ
- What the parser produces for malformed source and how to inspect it.
Complete example โ
examples/error_recovery.zig:
zig
for ([_][]const u8{ "1 + * 2", "(1 + 2", "1 @ 2" }) |source| {
var tree = try parser.parseString(source);
defer tree.deinit();
std.debug.print("{s} => has_error={} nodes={d}\n", .{ source, tree.hasError(), tree.nodeCount() });
}Expected output โ
text
1 + * 2 => has_error=true nodes=11
(1 + 2 => has_error=true nodes=15
1 @ 2 => has_error=true nodes=6How it works โ
- Unexpected tokens are skipped and the skipped span becomes an
ERRORleaf (named,isError(),hasError()set). Skipping accrues an error cost per byte, bounded by a maximum recovery budget. - Unexpected end of input inserts a zero-width
MISSINGtoken for the expected symbol (e.g. the missing)in(1 + 2) and continues parsing, so unclosed constructs still produce structured trees. - Unrecoverable states fall back to wrapping all fragments in a root node marked
hasError(), so a tree is always returned โ parsing never fails just because the source is broken. tree.hasError()/node.hasError()flag tainted subtrees; walk children forisError()/isMissing()to pinpoint problems for diagnostics.
API used โ
Related guides โ
- Testing for asserting recovery behavior, Troubleshooting.
- Error Recovery, Upstream Conformance.
