Skip to main content

oak_json/parser/
mod.rs

1pub mod element_type;
2
3use crate::{language::JsonLanguage, lexer::token_type::JsonTokenType, parser::element_type::JsonElementType};
4use oak_core::{OakError, Parser, ParserState, Source, TextEdit, TokenType};
5
6pub(crate) type State<'a, S> = ParserState<'a, JsonLanguage, S>;
7
8/// JSON 语言解析器
9pub struct JsonParser<'config> {
10    /// 语言配置
11    pub(crate) config: &'config JsonLanguage,
12}
13
14impl<'config> JsonParser<'config> {
15    pub fn new(config: &'config JsonLanguage) -> Self {
16        Self { config }
17    }
18
19    pub(crate) fn parse_value<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
20        self.skip_trivia(state);
21        let token = if let Some(t) = state.current() {
22            if t.kind == JsonTokenType::Eof {
23                return Err(state.unexpected_eof());
24            }
25            t
26        }
27        else {
28            return Err(state.unexpected_eof());
29        };
30
31        let kind = match token.kind {
32            JsonTokenType::LeftBrace => JsonTokenType::Object,
33            JsonTokenType::LeftBracket => JsonTokenType::Array,
34            JsonTokenType::StringLiteral => JsonTokenType::String,
35            JsonTokenType::NumberLiteral => JsonTokenType::Number,
36            JsonTokenType::BooleanLiteral => JsonTokenType::Boolean,
37            JsonTokenType::NullLiteral => JsonTokenType::Null,
38            _ => {
39                if self.config.bare_keys && token.kind == JsonTokenType::BareKey {
40                    state.record_unexpected_token(format!("{:?}", token.kind));
41                    return Err(state.errors.last().unwrap().clone());
42                }
43                state.record_unexpected_token(format!("{:?}", token.kind));
44                return Err(state.errors.last().unwrap().clone());
45            }
46        };
47
48        state.incremental_node(kind.into(), |state| match kind {
49            JsonTokenType::Object => self.parse_object(state),
50            JsonTokenType::Array => self.parse_array(state),
51            _ => {
52                state.bump();
53                Ok(())
54            }
55        })
56    }
57
58    fn parse_object<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
59        if !state.eat(JsonTokenType::LeftBrace) {
60            state.record_expected("{");
61            return Err(state.errors.last().cloned().expect("Error should have been recorded"));
62        }
63
64        let mut first = true;
65        while state.not_at_end() {
66            self.skip_trivia(state);
67            if state.at(JsonTokenType::RightBrace) {
68                break;
69            }
70
71            if state.at(JsonTokenType::Eof) {
72                return Err(state.unexpected_eof());
73            }
74
75            if !first {
76                if !state.eat(JsonTokenType::Comma) {
77                    state.record_expected(",");
78                    // Don't break here to try recover
79                    break;
80                }
81
82                self.skip_trivia(state);
83                if state.at(JsonTokenType::RightBrace) {
84                    if !self.config.trailing_comma {
85                        state.record_trailing_comma_not_allowed();
86                        return Err(state.errors.last().cloned().expect("Error should have been recorded"));
87                    }
88                    break;
89                }
90            }
91            first = false;
92
93            self.parse_object_entry(state)?;
94            self.skip_trivia(state);
95        }
96
97        if !state.eat(JsonTokenType::RightBrace) {
98            // Check if we are at EOF, if so return unexpected EOF
99            if state.at(JsonTokenType::Eof) || !state.not_at_end() {
100                return Err(state.unexpected_eof());
101            }
102            state.record_expected("}");
103            return Err(state.errors.last().cloned().expect("Error should have been recorded"));
104        }
105        Ok(())
106    }
107
108    fn parse_object_entry<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
109        state.incremental_node(JsonElementType::ObjectEntry, |state| {
110            if state.at(JsonTokenType::StringLiteral) || (self.config.bare_keys && state.at(JsonTokenType::BareKey)) {
111                state.bump();
112            }
113            else {
114                state.record_expected("key");
115                return Err(state.errors.last().cloned().expect("Error should have been recorded"));
116            }
117
118            self.skip_trivia(state);
119            if !state.eat(JsonTokenType::Colon) {
120                state.record_expected(":");
121            }
122            self.skip_trivia(state);
123            self.parse_value(state)?;
124            Ok(())
125        })
126    }
127
128    fn parse_array<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
129        if !state.eat(JsonTokenType::LeftBracket) {
130            state.record_expected("[");
131            return Err(state.errors.last().cloned().expect("Error should have been recorded"));
132        }
133
134        let mut first = true;
135        while state.not_at_end() {
136            self.skip_trivia(state);
137            if state.at(JsonTokenType::RightBracket) {
138                break;
139            }
140
141            if state.at(JsonTokenType::Eof) {
142                return Err(state.unexpected_eof());
143            }
144
145            if !first {
146                if !state.eat(JsonTokenType::Comma) {
147                    state.record_expected(",");
148                    break;
149                }
150
151                self.skip_trivia(state);
152                if state.at(JsonTokenType::RightBracket) {
153                    if !self.config.trailing_comma {
154                        state.record_trailing_comma_not_allowed();
155                        return Err(state.errors.last().cloned().expect("Error should have been recorded"));
156                    }
157                    break;
158                }
159            }
160            first = false;
161
162            self.parse_value(state)?;
163            self.skip_trivia(state);
164        }
165
166        if !state.eat(JsonTokenType::RightBracket) {
167            if state.at(JsonTokenType::Eof) || !state.not_at_end() {
168                return Err(state.unexpected_eof());
169            }
170            state.record_expected("]");
171            return Err(state.errors.last().cloned().expect("Error should have been recorded"));
172        }
173        Ok(())
174    }
175
176    fn skip_trivia<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
177        while let Some(token) = state.current() {
178            if token.kind.is_ignored() {
179                state.bump();
180            }
181            else {
182                break;
183            }
184        }
185    }
186}
187
188impl<'config> Parser<JsonLanguage> for JsonParser<'config> {
189    fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl oak_core::ParseCache<JsonLanguage>) -> oak_core::ParseOutput<'a, JsonLanguage> {
190        let lexer = crate::lexer::JsonLexer::new(self.config);
191        oak_core::parser::parse_with_lexer(&lexer, text, edits, cache, |state| {
192            let checkpoint = state.checkpoint();
193            let res = self.parse_value(state);
194            if res.is_err() {
195                // If parsing fails, we might still want to return a partial tree or an error tree
196                // But parse_value handles errors by returning Result<(), OakError>
197                // And it records errors in state.errors
198            }
199
200            // Ensure we consume all remaining trivia/whitespace
201            while state.not_at_end() {
202                if let Some(token) = state.current() {
203                    if token.kind.is_ignored() {
204                        state.bump(); // Changed from state.advance() to state.bump() to include in tree
205                        continue;
206                    }
207                }
208                break;
209            }
210
211            let root = state.finish_at(checkpoint, crate::parser::element_type::JsonElementType::Root);
212            Ok(root)
213        })
214    }
215}