Skip to main content

oak_vbnet/parser/
mod.rs

1/// Element type module
2pub mod element_type;
3
4mod parse_declaration;
5mod parse_expression;
6mod parse_member;
7mod parse_statement;
8
9use crate::{language::VbNetLanguage, lexer::token_type::VbNetTokenType, parser::element_type::VbNetElementType};
10use oak_core::{
11    OakError,
12    parser::{ParseCache, ParseOutput, Parser, ParserState, parse_with_lexer},
13    source::{Source, TextEdit},
14};
15
16pub(crate) type State<'a, S> = ParserState<'a, VbNetLanguage, S>;
17
18/// VB.NET parser
19pub struct VbNetParser<'config> {
20    pub(crate) config: &'config VbNetLanguage,
21}
22
23impl<'config> VbNetParser<'config> {
24    /// Creates a new VB.NET parser
25    pub fn new(config: &'config VbNetLanguage) -> Self {
26        Self { config }
27    }
28
29    pub(crate) fn skip_trivia<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
30        while let Some(kind) = state.peek_kind() {
31            match kind {
32                VbNetTokenType::Whitespace | VbNetTokenType::LineComment | VbNetTokenType::BlockComment | VbNetTokenType::Newline => {
33                    state.bump();
34                }
35                _ => break,
36            }
37        }
38    }
39}
40
41impl<'config> Parser<VbNetLanguage> for VbNetParser<'config> {
42    fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<VbNetLanguage>) -> ParseOutput<'a, VbNetLanguage> {
43        let lexer = crate::lexer::VbNetLexer::new(self.config);
44        parse_with_lexer(&lexer, text, edits, cache, |state| {
45            let cp = (0, 0);
46            while state.not_at_end() {
47                self.skip_trivia(state);
48                if state.not_at_end() {
49                    self.parse_statement(state)?;
50                }
51            }
52
53            Ok(state.finish_at(cp, VbNetElementType::Root))
54        })
55    }
56}