parse function
Stage 1: parse a dewbead document into ASTs without touching NOW.
Splits on ;; (which titles/locations cannot contain) and parses each
record independently. A document of exactly N yields empty lists.
Implementation
ParseAstResult parse(String document) {
final s = document.trim();
if (s.isEmpty) {
return (asts: const [], errors: [RecordError(ParseError.empty, document)]);
}
if (s == 'N') return (asts: const [], errors: const []);
final asts = <DewbeadAst>[];
final errors = <RecordError>[];
for (final raw in s.split(';;')) {
final seg = raw.trim();
try {
asts.add(_parseRecord(seg));
} on _ParseException catch (e) {
errors.add(RecordError(e.reason, seg));
}
}
return (asts: asts, errors: errors);
}