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