1pub mod element_type;
2
3use crate::{
4 language::PrologLanguage,
5 lexer::{PrologLexer, token_type::PrologTokenType},
6 parser::element_type::PrologElementType,
7};
8use oak_core::{
9 GreenNode, OakError,
10 parser::{ParseCache, ParseOutput, Parser, ParserState},
11 source::{Source, TextEdit},
12};
13
14pub struct PrologParser {
15 language: PrologLanguage,
16}
17
18impl PrologParser {
19 pub fn new(language: PrologLanguage) -> Self {
20 Self { language }
21 }
22
23 fn parse_directive<'s, S: Source + ?Sized>(&self, state: &mut ParserState<'s, PrologLanguage, S>) {
24 let checkpoint = state.checkpoint();
25 state.expect(PrologTokenType::ColonMinus).ok();
26 while !state.at(PrologTokenType::Dot) && state.not_at_end() {
27 state.bump()
28 }
29 state.expect(PrologTokenType::Dot).ok();
30 state.finish_at(checkpoint, crate::parser::element_type::PrologElementType::Directive);
31 }
32
33 fn parse_query<'s, S: Source + ?Sized>(&self, state: &mut ParserState<'s, PrologLanguage, S>) {
34 let checkpoint = state.checkpoint();
35 state.expect(PrologTokenType::QuestionMinus).ok();
36 while !state.at(PrologTokenType::Dot) && state.not_at_end() {
37 state.bump()
38 }
39 state.expect(PrologTokenType::Dot).ok();
40 state.finish_at(checkpoint, crate::parser::element_type::PrologElementType::Query);
41 }
42
43 fn parse_clause<'s, S: Source + ?Sized>(&self, state: &mut ParserState<'s, PrologLanguage, S>) {
44 let checkpoint = state.checkpoint();
45 while !state.at(PrologTokenType::Dot) && state.not_at_end() {
46 state.bump()
47 }
48 state.expect(PrologTokenType::Dot).ok();
49 state.finish_at(checkpoint, crate::parser::element_type::PrologElementType::Clause);
50 }
51
52 fn parse_root_internal<'s, S: Source + ?Sized>(&self, state: &mut ParserState<'s, PrologLanguage, S>) -> Result<&'s GreenNode<'s, PrologLanguage>, OakError> {
53 let checkpoint = state.checkpoint();
54 while state.not_at_end() {
55 if state.at(PrologTokenType::ColonMinus) {
56 self.parse_directive(state)
57 }
58 else if state.at(PrologTokenType::QuestionMinus) {
59 self.parse_query(state)
60 }
61 else {
62 self.parse_clause(state)
63 }
64 }
65 Ok(state.finish_at(checkpoint, crate::parser::element_type::PrologElementType::Root))
66 }
67}
68
69impl Parser<PrologLanguage> for PrologParser {
70 fn parse<'s, S: Source + ?Sized>(&self, text: &'s S, edits: &[TextEdit], cache: &'s mut impl ParseCache<PrologLanguage>) -> ParseOutput<'s, PrologLanguage> {
71 let lexer = PrologLexer::new(&self.language);
72 oak_core::parser::parse_with_lexer(&lexer, text, edits, cache, |state| self.parse_root_internal(state))
73 }
74}