oak_objective_c/parser/
mod.rs1use crate::{kind::ObjectiveCSyntaxKind, language::ObjectiveCLanguage, lexer::ObjectiveCLexer};
2use oak_core::{
3 parser::{ParseCache, ParseOutput, Parser, ParserState, parse_with_lexer},
4 source::{Source, TextEdit},
5};
6
7pub(crate) type State<'a, S> = ParserState<'a, ObjectiveCLanguage, S>;
8
9pub struct ObjectiveCParser<'config> {
10 pub language: &'config ObjectiveCLanguage,
11}
12
13impl<'config> ObjectiveCParser<'config> {
14 pub fn new(language: &'config ObjectiveCLanguage) -> Self {
15 Self { language }
16 }
17
18 fn parse_item<'b, S: Source + ?Sized>(&self, state: &mut State<'b, S>) {
19 if state.at(ObjectiveCSyntaxKind::At) {
20 state.bump();
21 if state.at(ObjectiveCSyntaxKind::InterfaceKeyword) {
22 self.parse_interface(state);
23 }
24 else if state.at(ObjectiveCSyntaxKind::ImplementationKeyword) {
25 self.parse_implementation(state);
26 }
27 else if state.at(ObjectiveCSyntaxKind::ProtocolKeyword) {
28 self.parse_protocol(state);
29 }
30 else {
31 let checkpoint = state.checkpoint();
32 state.bump();
33 state.finish_at(checkpoint, ObjectiveCSyntaxKind::Error.into());
34 }
35 }
36 else if state.at(ObjectiveCSyntaxKind::ImportKeyword) || state.at(ObjectiveCSyntaxKind::IncludeKeyword) {
37 self.parse_import(state);
38 }
39 else {
40 state.bump();
42 }
43 }
44
45 fn parse_interface<'b, S: Source + ?Sized>(&self, state: &mut State<'b, S>) {
46 let checkpoint = state.checkpoint();
47 state.expect(ObjectiveCSyntaxKind::InterfaceKeyword).ok();
48 while state.not_at_end() && !state.at(ObjectiveCSyntaxKind::EndKeyword) {
50 state.bump();
51 }
52 if state.at(ObjectiveCSyntaxKind::EndKeyword) {
53 state.expect(ObjectiveCSyntaxKind::EndKeyword).ok();
54 }
55 state.finish_at(checkpoint, ObjectiveCSyntaxKind::InterfaceDeclaration.into());
56 }
57
58 fn parse_implementation<'b, S: Source + ?Sized>(&self, state: &mut State<'b, S>) {
59 let checkpoint = state.checkpoint();
60 state.expect(ObjectiveCSyntaxKind::ImplementationKeyword).ok();
61 while state.not_at_end() && !state.at(ObjectiveCSyntaxKind::EndKeyword) {
63 state.bump();
64 }
65 if state.at(ObjectiveCSyntaxKind::EndKeyword) {
66 state.expect(ObjectiveCSyntaxKind::EndKeyword).ok();
67 }
68 state.finish_at(checkpoint, ObjectiveCSyntaxKind::ImplementationDeclaration.into());
69 }
70
71 fn parse_protocol<'b, S: Source + ?Sized>(&self, state: &mut State<'b, S>) {
72 let checkpoint = state.checkpoint();
73 state.expect(ObjectiveCSyntaxKind::ProtocolKeyword).ok();
74 while state.not_at_end() && !state.at(ObjectiveCSyntaxKind::EndKeyword) {
76 state.bump();
77 }
78 if state.at(ObjectiveCSyntaxKind::EndKeyword) {
79 state.expect(ObjectiveCSyntaxKind::EndKeyword).ok();
80 }
81 state.finish_at(checkpoint, ObjectiveCSyntaxKind::ProtocolDeclaration.into());
82 }
83
84 fn parse_import<'b, S: Source + ?Sized>(&self, state: &mut State<'b, S>) {
85 state.bump(); while state.not_at_end() && !state.at(ObjectiveCSyntaxKind::Semicolon) && !state.at(ObjectiveCSyntaxKind::Newline) {
88 state.bump();
89 }
90 if state.at(ObjectiveCSyntaxKind::Semicolon) {
91 state.expect(ObjectiveCSyntaxKind::Semicolon).ok();
92 }
93 }
94}
95
96impl<'config> Parser<ObjectiveCLanguage> for ObjectiveCParser<'config> {
97 fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<ObjectiveCLanguage>) -> ParseOutput<'a, ObjectiveCLanguage> {
98 let lexer = ObjectiveCLexer::new(self.language);
99 parse_with_lexer(&lexer, text, edits, cache, |state| {
100 let checkpoint = state.checkpoint();
101
102 while state.not_at_end() {
103 self.parse_item(state);
104 }
105
106 Ok(state.finish_at(checkpoint, ObjectiveCSyntaxKind::Root.into()))
107 })
108 }
109}