Skip to main content

oak_dsv/parser/
mod.rs

1#![doc = include_str!("readme.md")]
2/// Element types for the DSV language syntax tree.
3pub mod element_type;
4use crate::{
5    language::{Dsv, DsvLanguage},
6    lexer::DsvLexer,
7};
8pub use element_type::DsvElementType;
9use oak_core::{
10    ParseOutput,
11    parser::{ParseCache, Parser, ParserState},
12    source::{Source, TextEdit},
13};
14
15/// DSV parser state.
16pub(crate) type State<'a, const LANG: DsvLanguage, S> = ParserState<'a, Dsv<LANG>, S>;
17
18/// Parser for the DSV language.
19pub struct DsvParser<const LANG: DsvLanguage> {
20    _phantom: std::marker::PhantomData<Dsv<LANG>>,
21}
22
23impl<const LANG: DsvLanguage> Parser<Dsv<LANG>> for DsvParser<LANG> {
24    fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<Dsv<LANG>>) -> ParseOutput<'a, Dsv<LANG>> {
25        let lexer = DsvLexer::<LANG>::new();
26        oak_core::parser::parse_with_lexer(&lexer, text, edits, cache, |state| {
27            use crate::{lexer::DsvTokenType::*, parser::DsvElementType::*};
28            let cp = state.checkpoint();
29
30            while state.not_at_end() && !state.at(Eof) {
31                self.parse_record(state)?;
32                if state.at(Newline) {
33                    state.bump()
34                }
35            }
36
37            Ok(state.finish_at(cp, SourceFile))
38        })
39    }
40}
41
42impl<const LANG: DsvLanguage> DsvParser<LANG> {
43    /// Creates a new `DsvParser`.
44    pub fn new() -> Self {
45        Self { _phantom: std::marker::PhantomData }
46    }
47
48    /// Parses a DSV record.
49    fn parse_record<'a, S: oak_core::Source + ?Sized>(&self, state: &mut State<'a, LANG, S>) -> Result<(), oak_core::OakError> {
50        use crate::{lexer::DsvTokenType::*, parser::DsvElementType::*};
51        let cp = state.checkpoint();
52
53        self.parse_field(state)?;
54        while state.at(Separator) {
55            state.bump();
56            self.parse_field(state)?
57        }
58
59        state.finish_at(cp, Record);
60        Ok(())
61    }
62
63    /// Parses a DSV field.
64    fn parse_field<'a, S: oak_core::Source + ?Sized>(&self, state: &mut State<'a, LANG, S>) -> Result<(), oak_core::OakError> {
65        let cp = state.checkpoint();
66        if state.at(crate::lexer::DsvTokenType::Field) {
67            state.bump()
68        }
69        else {
70            // Empty field
71        }
72        state.finish_at(cp, DsvElementType::Field);
73        Ok(())
74    }
75}