1use super::ParseContext;
9use crate::parser::core::error::{ParseError, ParseErrorKind};
10use crate::parser::TokenKind;
11
12impl<'a> ParseContext<'a> {
13 pub fn expect_identifier(&mut self) -> Result<String, ParseError> {
14 match &self.current_token.kind {
15 TokenKind::Identifier(s) => {
16 let id = s.clone();
17 self.next_token();
18 Ok(id)
19 }
20 TokenKind::Count => {
22 self.next_token();
23 Ok("count".to_string())
24 }
25 TokenKind::Sum => {
26 self.next_token();
27 Ok("sum".to_string())
28 }
29 TokenKind::Avg => {
30 self.next_token();
31 Ok("avg".to_string())
32 }
33 TokenKind::Min => {
34 self.next_token();
35 Ok("min".to_string())
36 }
37 TokenKind::Max => {
38 self.next_token();
39 Ok("max".to_string())
40 }
41 TokenKind::Weight => {
42 self.next_token();
43 Ok("weight".to_string())
44 }
45 TokenKind::User | TokenKind::Order => {
46 let s = self.current_token.lexeme.clone();
47 self.next_token();
48 Ok(s)
49 }
50 TokenKind::Status => {
51 self.next_token();
52 Ok("status".to_string())
53 }
54 TokenKind::Contains => {
55 self.next_token();
56 Ok("CONTAINS".to_string())
57 }
58 TokenKind::Tags => {
59 self.next_token();
60 Ok("tags".to_string())
61 }
62 TokenKind::Tag => {
63 self.next_token();
64 Ok("tag".to_string())
65 }
66 TokenKind::Path => {
67 self.next_token();
68 Ok("path".to_string())
69 }
70 TokenKind::Vertex => {
71 self.next_token();
72 Ok("vertex".to_string())
73 }
74 TokenKind::KeywordVector => {
75 self.next_token();
76 Ok("VECTOR".to_string())
77 }
78 TokenKind::Vertices => {
79 self.next_token();
80 Ok("vertices".to_string())
81 }
82 TokenKind::Edges => {
83 self.next_token();
84 Ok("edges".to_string())
85 }
86 TokenKind::Admin
87 | TokenKind::God
88 | TokenKind::Dba
89 | TokenKind::Guest
90 | TokenKind::Space => {
91 let s = self.current_token.lexeme.clone();
92 self.next_token();
93 Ok(s)
94 }
95 TokenKind::Data | TokenKind::Transaction | TokenKind::Host => {
100 let s = self.current_token.lexeme.clone();
101 self.next_token();
102 Ok(s)
103 }
104 TokenKind::Read | TokenKind::Only | TokenKind::Write => {
107 let s = self.current_token.lexeme.clone();
108 self.next_token();
109 Ok(s)
110 }
111 TokenKind::Format | TokenKind::Header | TokenKind::Delimiter => {
113 let s = self.current_token.lexeme.clone();
114 self.next_token();
115 Ok(s)
116 }
117 TokenKind::Bool
122 | TokenKind::Int
123 | TokenKind::Int8
124 | TokenKind::Int16
125 | TokenKind::Int32
126 | TokenKind::Int64
127 | TokenKind::Float
128 | TokenKind::Double
129 | TokenKind::String
130 | TokenKind::FixedString
131 | TokenKind::Timestamp
132 | TokenKind::Date
133 | TokenKind::Time
134 | TokenKind::Datetime
135 | TokenKind::Serial
136 | TokenKind::Geography
137 | TokenKind::List
138 | TokenKind::Map
139 | TokenKind::Struct
140 | TokenKind::Array
141 | TokenKind::UUID
142 | TokenKind::Duration => {
143 let s = self.current_token.lexeme.clone();
144 self.next_token();
145 Ok(s)
146 }
147 _ => {
148 let pos = self.current_position();
149 Err(ParseError::new(
150 ParseErrorKind::UnexpectedToken,
151 format!("Expected identifier, found {:?}", self.current_token.kind),
152 pos,
153 )
154 .with_expected_tokens(vec!["identifier".to_string()]))
155 }
156 }
157 }
158
159 pub fn expect_boolean_literal(&mut self) -> Result<bool, ParseError> {
165 match self.current_token.kind {
166 TokenKind::BooleanLiteral(value) => {
167 self.next_token();
168 Ok(value)
169 }
170 _ => {
171 let pos = self.current_position();
172 Err(ParseError::new(
173 ParseErrorKind::UnexpectedToken,
174 format!(
175 "Expected boolean value, found {:?}",
176 self.current_token.kind
177 ),
178 pos,
179 )
180 .with_expected_tokens(vec!["true".to_string(), "false".to_string()]))
181 }
182 }
183 }
184
185 pub fn expect_dcl_name(&mut self) -> Result<String, ParseError> {
190 let mut name = self.expect_dcl_name_part()?;
191 while self.match_token(TokenKind::Minus) {
192 name.push('-');
193 name.push_str(&self.expect_dcl_name_part()?);
194 }
195 Ok(name)
196 }
197
198 fn expect_dcl_name_part(&mut self) -> Result<String, ParseError> {
199 let token = self.current_token().clone();
200 match &token.kind {
201 TokenKind::Identifier(s) | TokenKind::StringLiteral(s) => {
202 let s = s.clone();
203 self.next_token();
204 Ok(s)
205 }
206 TokenKind::IntegerLiteral(_) => {
207 let lexeme = token.lexeme.clone();
208 self.next_token();
209 Ok(lexeme)
210 }
211 _ => {
212 if matches!(
216 token.kind,
217 TokenKind::With
218 | TokenKind::Password
219 | TokenKind::Role
220 | TokenKind::To
221 | TokenKind::From
222 | TokenKind::On
223 | TokenKind::In
224 | TokenKind::If
225 | TokenKind::Exists
226 | TokenKind::Set
227 | TokenKind::Locked
228 ) {
229 let pos = self.current_position();
230 return Err(ParseError::new(
231 ParseErrorKind::UnexpectedToken,
232 format!("Expected name, found {:?}", self.current_token.kind),
233 pos,
234 ));
235 }
236 if token.lexeme.is_empty() {
237 let pos = self.current_position();
238 Err(ParseError::new(
239 ParseErrorKind::UnexpectedToken,
240 format!("Expected name, found {:?}", self.current_token.kind),
241 pos,
242 ))
243 } else {
244 let lexeme = token.lexeme.clone();
245 self.next_token();
246 Ok(lexeme)
247 }
248 }
249 }
250 }
251
252 pub fn expect_string_literal(&mut self) -> Result<String, ParseError> {
253 match &self.current_token.kind {
254 TokenKind::StringLiteral(s) => {
255 let s = s.clone();
256 self.next_token();
257 Ok(s)
258 }
259 _ => {
260 let pos = self.current_position();
261 Err(ParseError::new(
262 ParseErrorKind::UnexpectedToken,
263 format!(
264 "Expected string literal, found {:?}",
265 self.current_token.kind
266 ),
267 pos,
268 )
269 .with_expected_tokens(vec!["string literal".to_string()]))
270 }
271 }
272 }
273
274 pub fn expect_integer_literal(&mut self) -> Result<i64, ParseError> {
275 match &self.current_token.kind {
276 TokenKind::IntegerLiteral(n) => {
277 let n = *n;
278 self.next_token();
279 Ok(n)
280 }
281 _ => {
282 let pos = self.current_position();
283 Err(ParseError::new(
284 ParseErrorKind::UnexpectedToken,
285 format!(
286 "Expected integer literal, found {:?}",
287 self.current_token.kind
288 ),
289 pos,
290 )
291 .with_expected_tokens(vec!["integer literal".to_string()]))
292 }
293 }
294 }
295
296 pub fn expect_float_literal(&mut self) -> Result<f64, ParseError> {
297 match &self.current_token.kind {
298 TokenKind::FloatLiteral(f) => {
299 let f = *f;
300 self.next_token();
301 Ok(f)
302 }
303 _ => {
304 let pos = self.current_position();
305 Err(ParseError::new(
306 ParseErrorKind::UnexpectedToken,
307 format!(
308 "Expected float literal, found {:?}",
309 self.current_token.kind
310 ),
311 pos,
312 )
313 .with_expected_tokens(vec!["float literal".to_string()]))
314 }
315 }
316 }
317
318 pub fn is_identifier_or_in_token(&self) -> bool {
319 matches!(
320 self.current_token.kind,
321 TokenKind::Identifier(_) | TokenKind::In
322 )
323 }
324
325 pub fn is_identifier_token(&self) -> bool {
326 matches!(
327 self.current_token.kind,
328 TokenKind::Identifier(_)
329 | TokenKind::Count
330 | TokenKind::Sum
331 | TokenKind::Avg
332 | TokenKind::Min
333 | TokenKind::Max
334 | TokenKind::Weight
335 | TokenKind::User
336 | TokenKind::Order
337 | TokenKind::Status
338 | TokenKind::Contains
339 | TokenKind::Tag
340 | TokenKind::Tags
341 | TokenKind::Path
342 | TokenKind::Vertex
343 | TokenKind::Vertices
344 | TokenKind::Edges
345 )
346 }
347
348 pub fn check_keyword(&mut self, keyword: &str) -> bool {
349 match &self.current_token.kind {
350 TokenKind::Identifier(kw) => kw.eq_ignore_ascii_case(keyword),
351 TokenKind::Index => keyword.eq_ignore_ascii_case("INDEX"),
352 TokenKind::On => keyword.eq_ignore_ascii_case("ON"),
353 TokenKind::Drop => keyword.eq_ignore_ascii_case("DROP"),
354 TokenKind::Create => keyword.eq_ignore_ascii_case("CREATE"),
355 TokenKind::Alter => keyword.eq_ignore_ascii_case("ALTER"),
356 TokenKind::Show => keyword.eq_ignore_ascii_case("SHOW"),
357 TokenKind::Desc => {
358 keyword.eq_ignore_ascii_case("DESC") || keyword.eq_ignore_ascii_case("DESCRIBE")
359 }
360 TokenKind::Search => keyword.eq_ignore_ascii_case("SEARCH"),
361 TokenKind::Lookup => keyword.eq_ignore_ascii_case("LOOKUP"),
362 TokenKind::Match => keyword.eq_ignore_ascii_case("MATCH"),
363 TokenKind::KeywordVector => keyword.eq_ignore_ascii_case("VECTOR"),
364 TokenKind::If => keyword.eq_ignore_ascii_case("IF"),
365 TokenKind::Not => keyword.eq_ignore_ascii_case("NOT"),
366 TokenKind::Exists => keyword.eq_ignore_ascii_case("EXISTS"),
367 TokenKind::User => keyword.eq_ignore_ascii_case("USER"),
368 TokenKind::Tag => keyword.eq_ignore_ascii_case("TAG"),
369 TokenKind::Edge => keyword.eq_ignore_ascii_case("EDGE"),
370 TokenKind::Space => keyword.eq_ignore_ascii_case("SPACE"),
371 TokenKind::Insert => keyword.eq_ignore_ascii_case("INSERT"),
372 TokenKind::Delete => keyword.eq_ignore_ascii_case("DELETE"),
373 TokenKind::Detach => keyword.eq_ignore_ascii_case("DETACH"),
374 TokenKind::Update => keyword.eq_ignore_ascii_case("UPDATE"),
375 TokenKind::Return => keyword.eq_ignore_ascii_case("RETURN"),
376 TokenKind::Where => keyword.eq_ignore_ascii_case("WHERE"),
377 TokenKind::Set => keyword.eq_ignore_ascii_case("SET"),
378 TokenKind::Remove => keyword.eq_ignore_ascii_case("REMOVE"),
379 TokenKind::Add => keyword.eq_ignore_ascii_case("ADD"),
380 TokenKind::With => keyword.eq_ignore_ascii_case("WITH"),
381 TokenKind::Yield => keyword.eq_ignore_ascii_case("YIELD"),
382 TokenKind::Go => keyword.eq_ignore_ascii_case("GO"),
383 TokenKind::Over => keyword.eq_ignore_ascii_case("OVER"),
384 TokenKind::Step => keyword.eq_ignore_ascii_case("STEP"),
385 TokenKind::Upto => keyword.eq_ignore_ascii_case("UPTO"),
386 TokenKind::Limit => keyword.eq_ignore_ascii_case("LIMIT"),
387 TokenKind::Asc => keyword.eq_ignore_ascii_case("ASC"),
388 TokenKind::Order => keyword.eq_ignore_ascii_case("ORDER"),
389 TokenKind::By => keyword.eq_ignore_ascii_case("BY"),
390 TokenKind::Skip => keyword.eq_ignore_ascii_case("SKIP"),
391 TokenKind::Unwind => keyword.eq_ignore_ascii_case("UNWIND"),
392 TokenKind::Optional => keyword.eq_ignore_ascii_case("OPTIONAL"),
393 TokenKind::Distinct => keyword.eq_ignore_ascii_case("DISTINCT"),
394 TokenKind::All => keyword.eq_ignore_ascii_case("ALL"),
395 TokenKind::Null => keyword.eq_ignore_ascii_case("NULL"),
396 TokenKind::Is => keyword.eq_ignore_ascii_case("IS"),
397 TokenKind::And => keyword.eq_ignore_ascii_case("AND"),
398 TokenKind::Or => keyword.eq_ignore_ascii_case("OR"),
399 TokenKind::Xor => keyword.eq_ignore_ascii_case("XOR"),
400 TokenKind::Contains => keyword.eq_ignore_ascii_case("CONTAINS"),
401 TokenKind::StartsWith => keyword.eq_ignore_ascii_case("STARTS WITH"),
402 TokenKind::EndsWith => keyword.eq_ignore_ascii_case("ENDS WITH"),
403 TokenKind::Case => keyword.eq_ignore_ascii_case("CASE"),
404 TokenKind::When => keyword.eq_ignore_ascii_case("WHEN"),
405 TokenKind::Then => keyword.eq_ignore_ascii_case("THEN"),
406 TokenKind::Else => keyword.eq_ignore_ascii_case("ELSE"),
407 TokenKind::End => keyword.eq_ignore_ascii_case("END"),
408 TokenKind::Union => keyword.eq_ignore_ascii_case("UNION"),
409 TokenKind::Intersect => keyword.eq_ignore_ascii_case("INTERSECT"),
410 TokenKind::SetMinus => keyword.eq_ignore_ascii_case("SET MINUS"),
411 TokenKind::Group => keyword.eq_ignore_ascii_case("GROUP"),
412 TokenKind::Having => keyword.eq_ignore_ascii_case("HAVING"),
413 TokenKind::Between => keyword.eq_ignore_ascii_case("BETWEEN"),
414 TokenKind::Comment => keyword.eq_ignore_ascii_case("COMMENT"),
415 TokenKind::Admin => keyword.eq_ignore_ascii_case("ADMIN"),
416 TokenKind::Edges => keyword.eq_ignore_ascii_case("EDGES"),
417 TokenKind::Vertex => keyword.eq_ignore_ascii_case("VERTEX"),
418 TokenKind::Vertices => keyword.eq_ignore_ascii_case("VERTICES"),
419 TokenKind::Tags => keyword.eq_ignore_ascii_case("TAGS"),
420 TokenKind::Indexes => keyword.eq_ignore_ascii_case("INDEXES"),
421 TokenKind::Find => keyword.eq_ignore_ascii_case("FIND"),
422 TokenKind::Path => keyword.eq_ignore_ascii_case("PATH"),
423 TokenKind::From => keyword.eq_ignore_ascii_case("FROM"),
424 TokenKind::To => keyword.eq_ignore_ascii_case("TO"),
425 TokenKind::As => keyword.eq_ignore_ascii_case("AS"),
426 TokenKind::Upsert => keyword.eq_ignore_ascii_case("UPSERT"),
427 TokenKind::In => keyword.eq_ignore_ascii_case("IN"),
428 TokenKind::Rollback => keyword.eq_ignore_ascii_case("ROLLBACK"),
429 _ => false,
430 }
431 }
432
433 pub fn check_keyword_sequence(&mut self, keywords: &[&str]) -> bool {
435 if keywords.is_empty() {
436 return false;
437 }
438
439 let saved_lexer = self.lexer.clone();
441 let saved_token = self.current_token.clone();
442
443 for (i, &keyword) in keywords.iter().enumerate() {
445 if i > 0 {
446 self.next_token();
447 }
448 if !self.check_keyword(keyword) {
449 self.lexer = saved_lexer;
451 self.current_token = saved_token;
452 return false;
453 }
454 }
455
456 self.lexer = saved_lexer;
458 self.current_token = saved_token;
459 true
460 }
461
462 pub fn consume_keyword(&mut self, keyword: &str) -> Result<(), ParseError> {
463 if self.check_keyword(keyword) {
464 self.next_token();
465 Ok(())
466 } else {
467 let pos = self.current_position();
468 Err(ParseError::new(
469 ParseErrorKind::UnexpectedToken,
470 format!(
471 "Expected keyword '{}', found {:?}",
472 keyword, self.current_token.kind
473 ),
474 pos,
475 ))
476 }
477 }
478
479 pub fn consume_identifier(&mut self) -> Result<String, ParseError> {
480 self.expect_identifier()
481 }
482
483 pub fn consume_string(&mut self) -> Result<String, ParseError> {
484 self.expect_string_literal()
485 }
486
487 pub fn consume_float(&mut self) -> Result<f64, ParseError> {
488 self.expect_float_literal()
489 }
490
491 pub fn consume_int(&mut self) -> Result<i64, ParseError> {
492 self.expect_integer_literal()
493 }
494
495 pub fn consume_token(&mut self, token: &str) -> Result<(), ParseError> {
496 match token {
497 "(" => self.expect_token(TokenKind::LParen),
498 ")" => self.expect_token(TokenKind::RParen),
499 "," => self.expect_token(TokenKind::Comma),
500 ";" => self.expect_token(TokenKind::Semicolon),
501 ":" => self.expect_token(TokenKind::Colon),
502 "+" => self.expect_token(TokenKind::Plus),
503 "-" => self.expect_token(TokenKind::Minus),
504 "*" => self.expect_token(TokenKind::Star),
505 "/" => self.expect_token(TokenKind::Div),
506 "=" => self.expect_token(TokenKind::Eq),
507 "!=" => self.expect_token(TokenKind::Ne),
508 "<" => self.expect_token(TokenKind::Lt),
509 "<=" => self.expect_token(TokenKind::Le),
510 ">" => self.expect_token(TokenKind::Gt),
511 ">=" => self.expect_token(TokenKind::Ge),
512 _ => {
513 let pos = self.current_position();
514 Err(ParseError::new(
515 ParseErrorKind::UnexpectedToken,
516 format!("Unsupported token: {}", token),
517 pos,
518 ))
519 }
520 }
521 }
522
523 pub fn consume_optional_token(&mut self, token: &str) -> bool {
524 match token {
525 "(" => self.match_token(TokenKind::LParen),
526 ")" => self.match_token(TokenKind::RParen),
527 "," => self.match_token(TokenKind::Comma),
528 ";" => self.match_token(TokenKind::Semicolon),
529 ":" => self.match_token(TokenKind::Colon),
530 "+" => self.match_token(TokenKind::Plus),
531 "-" => self.match_token(TokenKind::Minus),
532 "*" => self.match_token(TokenKind::Star),
533 "/" => self.match_token(TokenKind::Div),
534 "=" => self.match_token(TokenKind::Eq),
535 "!=" => self.match_token(TokenKind::Ne),
536 "<" => self.match_token(TokenKind::Lt),
537 "<=" => self.match_token(TokenKind::Le),
538 ">" => self.match_token(TokenKind::Gt),
539 ">=" => self.match_token(TokenKind::Ge),
540 _ => false,
541 }
542 }
543
544 pub fn try_consume_string(&mut self) -> Option<String> {
545 if let TokenKind::StringLiteral(s) = &self.current_token.kind {
546 let s = s.clone();
547 self.next_token();
548 Some(s)
549 } else {
550 None
551 }
552 }
553
554 pub fn try_consume_quoted_string(&mut self) -> Option<String> {
555 self.try_consume_string()
556 }
557}