chronlang_parser/
parser.rs

1use chumsky::{prelude::*, text::{newline, whitespace}};
2
3use crate::ast::{Stmt, Spanned};
4
5mod class_definition;
6mod series_definition;
7mod common;
8mod import;
9mod lang_definition;
10mod sound_change;
11mod trait_definition;
12mod word_definition;
13mod milestone;
14
15fn stmt() -> impl Parser<char, Spanned<Stmt>, Error = Simple<char>> {
16  choice([
17    sound_change::parser().boxed(),
18    import::parser().boxed(),
19    lang_definition::parser().boxed(),
20    word_definition::parser().boxed(),
21    trait_definition::parser().boxed(),
22    class_definition::parser().boxed(),
23    series_definition::parser().boxed(),
24    milestone::parser().boxed(),
25  ])
26    .map_with_span(|stmt, span| (span, stmt))
27    .then_ignore(newline().repeated().at_least(1).ignored().or(end()))
28    .then_ignore(whitespace())
29}
30
31fn root() -> impl Parser<char, Vec<Spanned<Stmt>>, Error = Simple<char>> {
32  stmt()
33    .repeated()
34    .padded()
35    .then_ignore(end())
36}
37
38pub fn parse(source: &str) -> Result<Vec<(std::ops::Range<usize>, Stmt)>, Vec<chumsky::error::Simple<char>>> {
39  root().parse(source)
40}