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