1mod path_reader;
2mod tokenizer;
3
4use std::str::FromStr;
5
6use self::tokenizer::*;
7
8const DUMMY: usize = 0;
9
10type ParseResult<T> = Result<T, String>;
11
12mod utils {
13 use std::str::FromStr;
14
15 pub fn string_to_num<F, S: FromStr>(string: &str, msg_handler: F) -> Result<S, String>
16 where
17 F: Fn() -> String,
18 {
19 match string.parse() {
20 Ok(n: S) => Ok(n),
21 _ => Err(msg_handler()),
22 }
23 }
24}
25
26#[derive(Debug, PartialEq, Clone)]
27pub enum ParseToken {
28 // '$'
29 Absolute,
30 // '@'
31 Relative,
32 // '.'
33 In,
34 // '..'
35 Leaves,
36 // '*'
37 All,
38
39 Key(String),
40 Keys(Vec<String>),
41 // []
42 Array,
43 // 메타토큰
44 ArrayEof,
45 // ?( filter )
46 Filter(FilterToken),
47 // 1 : 2
48 Range(Option<isize>, Option<isize>, Option<usize>),
49 // 1, 2, 3
50 Union(Vec<isize>),
51
52 Number(f64),
53
54 Bool(bool),
55
56 Eof,
57}
58
59#[derive(Debug, PartialEq, Clone)]
60pub enum FilterToken {
61 Equal,
62 NotEqual,
63 Little,
64 LittleOrEqual,
65 Greater,
66 GreaterOrEqual,
67 And,
68 Or,
69}
70
71#[derive(Debug, Clone)]
72pub struct Node {
73 left: Option<Box<Node>>,
74 right: Option<Box<Node>>,
75 token: ParseToken,
76}
77
78pub struct Parser;
79
80impl Parser {
81 pub fn compile(input: &str) -> ParseResult<Node> {
82 let mut tokenizer = TokenReader::new(input);
83 Self::json_path(&mut tokenizer)
84 }
85
86 fn json_path(tokenizer: &mut TokenReader) -> ParseResult<Node> {
87 debug!("#json_path");
88 match tokenizer.next_token() {
89 Ok(Token::Absolute(_)) => {
90 let node = Self::node(ParseToken::Absolute);
91 Self::paths(node, tokenizer)
92 }
93 _ => Err(tokenizer.err_msg()),
94 }
95 }
96
97 fn paths(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
98 debug!("#paths");
99 match tokenizer.peek_token() {
100 Ok(Token::Dot(_)) => {
101 Self::eat_token(tokenizer);
102 Self::paths_dot(prev, tokenizer)
103 }
104 Ok(Token::OpenArray(_)) => {
105 Self::eat_token(tokenizer);
106 Self::eat_whitespace(tokenizer);
107 let node = Self::array(prev, tokenizer)?;
108 Self::paths(node, tokenizer)
109 }
110 _ => Ok(prev),
111 }
112 }
113
114 fn paths_dot(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
115 debug!("#paths_dot");
116 let node = Self::path(prev, tokenizer)?;
117 Self::paths(node, tokenizer)
118 }
119
120 fn path(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
121 debug!("#path");
122 match tokenizer.peek_token() {
123 Ok(Token::Dot(_)) => Self::path_leaves(prev, tokenizer),
124 Ok(Token::Asterisk(_)) => Self::path_in_all(prev, tokenizer),
125 Ok(Token::Key(_, _)) => Self::path_in_key(prev, tokenizer),
126 Ok(Token::OpenArray(_)) => {
127 Self::eat_token(tokenizer);
128 Self::array(prev, tokenizer)
129 }
130 _ => Err(tokenizer.err_msg()),
131 }
132 }
133
134 fn path_leaves(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
135 debug!("#path_leaves");
136 Self::eat_token(tokenizer);
137 match tokenizer.peek_token() {
138 Ok(Token::Asterisk(_)) => Self::path_leaves_all(prev, tokenizer),
139 Ok(Token::OpenArray(_)) => {
140 let mut leaves_node = Self::node(ParseToken::Leaves);
141 leaves_node.left = Some(Box::new(prev));
142 Ok(Self::paths(leaves_node, tokenizer)?)
143 }
144 _ => Self::path_leaves_key(prev, tokenizer),
145 }
146 }
147
148 #[allow(clippy::unnecessary_wraps)]
149 fn path_leaves_key(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
150 debug!("#path_leaves_key");
151 Ok(Node {
152 token: ParseToken::Leaves,
153 left: Some(Box::new(prev)),
154 right: Some(Box::new(Self::key(tokenizer)?)),
155 })
156 }
157
158 #[allow(clippy::unnecessary_wraps)]
159 fn path_leaves_all(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
160 debug!("#path_leaves_all");
161 Self::eat_token(tokenizer);
162 Ok(Node {
163 token: ParseToken::Leaves,
164 left: Some(Box::new(prev)),
165 right: Some(Box::new(Self::node(ParseToken::All))),
166 })
167 }
168
169 #[allow(clippy::unnecessary_wraps)]
170 fn path_in_all(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
171 debug!("#path_in_all");
172 Self::eat_token(tokenizer);
173 Ok(Node {
174 token: ParseToken::In,
175 left: Some(Box::new(prev)),
176 right: Some(Box::new(Self::node(ParseToken::All))),
177 })
178 }
179
180 #[allow(clippy::unnecessary_wraps)]
181 fn path_in_key(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
182 debug!("#path_in_key");
183 Ok(Node {
184 token: ParseToken::In,
185 left: Some(Box::new(prev)),
186 right: Some(Box::new(Self::key(tokenizer)?)),
187 })
188 }
189
190 fn key(tokenizer: &mut TokenReader) -> ParseResult<Node> {
191 debug!("#key");
192 match tokenizer.next_token() {
193 Ok(Token::Key(_, v)) => Ok(Self::node(ParseToken::Key(v))),
194 _ => Err(tokenizer.err_msg()),
195 }
196 }
197
198 fn boolean(tokenizer: &mut TokenReader) -> ParseResult<Node> {
199 debug!("#boolean");
200
201 fn validation_bool_value(v: &str) -> bool {
202 let b = v.as_bytes();
203 !b.is_empty() && (b[0] == b't' || b[0] == b'T' || b[0] == b'f' || b[0] == b'F')
204 }
205
206 match tokenizer.next_token() {
207 Ok(Token::Key(_, ref v)) if validation_bool_value(v) => {
208 Ok(Self::node(ParseToken::Bool(v.eq_ignore_ascii_case("true"))))
209 }
210 _ => Err(tokenizer.err_msg()),
211 }
212 }
213
214 fn array_keys(tokenizer: &mut TokenReader, first_key: String) -> ParseResult<Node> {
215 let mut keys = vec![first_key];
216
217 while let Ok(Token::Comma(_)) = tokenizer.peek_token() {
218 Self::eat_token(tokenizer);
219 Self::eat_whitespace(tokenizer);
220
221 match tokenizer.next_token() {
222 Ok(Token::SingleQuoted(_, val)) | Ok(Token::DoubleQuoted(_, val)) => {
223 keys.push(val);
224 }
225 _ => return Err(tokenizer.err_msg()),
226 }
227
228 Self::eat_whitespace(tokenizer);
229 }
230
231 Ok(Self::node(ParseToken::Keys(keys)))
232 }
233
234 fn array_quote_value(tokenizer: &mut TokenReader) -> ParseResult<Node> {
235 debug!("#array_quote_value");
236 match tokenizer.next_token() {
237 Ok(Token::SingleQuoted(_, val)) | Ok(Token::DoubleQuoted(_, val)) => {
238 if let Ok(Token::Comma(_)) = tokenizer.peek_token() {
239 Self::array_keys(tokenizer, val)
240 } else {
241 Ok(Self::node(ParseToken::Key(val)))
242 }
243 }
244 _ => Err(tokenizer.err_msg()),
245 }
246 }
247
248 fn array_start(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
249 debug!("#array_start");
250 match tokenizer.peek_token() {
251 Ok(Token::Question(_)) => {
252 Self::eat_token(tokenizer);
253 Ok(Node {
254 token: ParseToken::Array,
255 left: Some(Box::new(prev)),
256 right: Some(Box::new(Self::filter(tokenizer)?)),
257 })
258 }
259 Ok(Token::Asterisk(_)) => {
260 Self::eat_token(tokenizer);
261 Ok(Node {
262 token: ParseToken::Array,
263 left: Some(Box::new(prev)),
264 right: Some(Box::new(Self::node(ParseToken::All))),
265 })
266 }
267 _ => Ok(Node {
268 token: ParseToken::Array,
269 left: Some(Box::new(prev)),
270 right: Some(Box::new(Self::array_value(tokenizer)?)),
271 }),
272 }
273 }
274
275 fn array(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
276 debug!("#array");
277 let ret = Self::array_start(prev, tokenizer)?;
278 Self::eat_whitespace(tokenizer);
279 Self::close_token(ret, Token::CloseArray(DUMMY), tokenizer)
280 }
281
282 fn array_value_key(tokenizer: &mut TokenReader) -> ParseResult<Node> {
283 debug!("#array_value_key");
284 match tokenizer.next_token() {
285 Ok(Token::Key(pos, ref val)) => {
286 let digit = utils::string_to_num(val, || tokenizer.err_msg_with_pos(pos))?;
287 Self::eat_whitespace(tokenizer);
288
289 match tokenizer.peek_token() {
290 Ok(Token::Comma(_)) => Self::union(digit, tokenizer),
291 Ok(Token::Split(_)) => Self::range_from(digit, tokenizer),
292 _ => Ok(Self::node(ParseToken::Number(digit as f64))),
293 }
294 }
295 _ => Err(tokenizer.err_msg()),
296 }
297 }
298
299 fn array_value(tokenizer: &mut TokenReader) -> ParseResult<Node> {
300 debug!("#array_value");
301 match tokenizer.peek_token() {
302 Ok(Token::Key(_, _)) => Self::array_value_key(tokenizer),
303 Ok(Token::Split(_)) => {
304 Self::eat_token(tokenizer);
305 Self::range_to(tokenizer)
306 }
307 Ok(Token::DoubleQuoted(_, _)) | Ok(Token::SingleQuoted(_, _)) => {
308 Self::array_quote_value(tokenizer)
309 }
310 Err(TokenError::Eof) => Ok(Self::node(ParseToken::Eof)),
311 _ => {
312 Self::eat_token(tokenizer);
313 Err(tokenizer.err_msg())
314 }
315 }
316 }
317
318 fn union(num: isize, tokenizer: &mut TokenReader) -> ParseResult<Node> {
319 debug!("#union");
320 let mut values = vec![num];
321 while matches!(tokenizer.peek_token(), Ok(Token::Comma(_))) {
322 Self::eat_token(tokenizer);
323 Self::eat_whitespace(tokenizer);
324 match tokenizer.next_token() {
325 Ok(Token::Key(pos, ref val)) => {
326 let digit = utils::string_to_num(val, || tokenizer.err_msg_with_pos(pos))?;
327 values.push(digit);
328 }
329 _ => {
330 return Err(tokenizer.err_msg());
331 }
332 }
333 }
334 Ok(Self::node(ParseToken::Union(values)))
335 }
336
337 fn range_value<S: FromStr>(tokenizer: &mut TokenReader) -> Result<Option<S>, String> {
338 Self::eat_whitespace(tokenizer);
339
340 match tokenizer.peek_token() {
341 Ok(Token::Split(_)) => {
342 Self::eat_token(tokenizer);
343 Self::eat_whitespace(tokenizer);
344 }
345 _ => {
346 return Ok(None);
347 }
348 }
349
350 match tokenizer.peek_token() {
351 Ok(Token::Key(_, _)) => {}
352 _ => {
353 return Ok(None);
354 }
355 }
356
357 match tokenizer.next_token() {
358 Ok(Token::Key(pos, str_step)) => {
359 match utils::string_to_num(&str_step, || tokenizer.err_msg_with_pos(pos)) {
360 Ok(step) => Ok(Some(step)),
361 Err(e) => Err(e),
362 }
363 }
364 _ => {
365 unreachable!();
366 }
367 }
368 }
369
370 fn range_from(from: isize, tokenizer: &mut TokenReader) -> ParseResult<Node> {
371 debug!("#range_from");
372 Self::eat_token(tokenizer);
373 Self::eat_whitespace(tokenizer);
374
375 match tokenizer.peek_token() {
376 Ok(Token::Key(_, _)) => Self::range(from, tokenizer),
377 Ok(Token::Split(_)) => match Self::range_value(tokenizer)? {
378 Some(step) => Ok(Self::node(ParseToken::Range(Some(from), None, Some(step)))),
379 _ => Ok(Self::node(ParseToken::Range(Some(from), None, None))),
380 },
381 _ => Ok(Self::node(ParseToken::Range(Some(from), None, None))),
382 }
383 }
384
385 fn range_to(tokenizer: &mut TokenReader) -> ParseResult<Node> {
386 debug!("#range_to");
387
388 if let Some(step) = Self::range_value(tokenizer)? {
389 return Ok(Self::node(ParseToken::Range(None, None, Some(step))));
390 }
391
392 if let Ok(Token::CloseArray(_)) = tokenizer.peek_token() {
393 return Ok(Self::node(ParseToken::Range(None, None, None)));
394 }
395
396 match tokenizer.next_token() {
397 Ok(Token::Key(pos, ref to_str)) => {
398 let to = utils::string_to_num(to_str, || tokenizer.err_msg_with_pos(pos))?;
399 let step = Self::range_value(tokenizer)?;
400 Ok(Self::node(ParseToken::Range(None, Some(to), step)))
401 }
402 _ => Err(tokenizer.err_msg()),
403 }
404 }
405
406 fn range(from: isize, tokenizer: &mut TokenReader) -> ParseResult<Node> {
407 debug!("#range");
408 match tokenizer.next_token() {
409 Ok(Token::Key(pos, ref str_to)) => {
410 let to = utils::string_to_num(str_to, || tokenizer.err_msg_with_pos(pos))?;
411 let step = Self::range_value(tokenizer)?;
412 Ok(Self::node(ParseToken::Range(Some(from), Some(to), step)))
413 }
414 _ => Err(tokenizer.err_msg()),
415 }
416 }
417
418 fn filter(tokenizer: &mut TokenReader) -> ParseResult<Node> {
419 debug!("#filter");
420 match tokenizer.next_token() {
421 Ok(Token::OpenParenthesis(_)) => {
422 let ret = Self::exprs(tokenizer)?;
423 Self::eat_whitespace(tokenizer);
424 Self::close_token(ret, Token::CloseParenthesis(DUMMY), tokenizer)
425 }
426 _ => Err(tokenizer.err_msg()),
427 }
428 }
429
430 fn exprs(tokenizer: &mut TokenReader) -> ParseResult<Node> {
431 Self::eat_whitespace(tokenizer);
432 debug!("#exprs");
433 let node = match tokenizer.peek_token() {
434 Ok(Token::OpenParenthesis(_)) => {
435 Self::eat_token(tokenizer);
436 trace!("\t-exprs - open_parenthesis");
437 let ret = Self::exprs(tokenizer)?;
438 Self::eat_whitespace(tokenizer);
439 Self::close_token(ret, Token::CloseParenthesis(DUMMY), tokenizer)?
440 }
441 _ => {
442 trace!("\t-exprs - else");
443 Self::expr(tokenizer)?
444 }
445 };
446 Self::eat_whitespace(tokenizer);
447 Self::condition_expr(node, tokenizer)
448 }
449
450 fn condition_expr(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
451 debug!("#condition_expr");
452 match tokenizer.peek_token() {
453 Ok(Token::And(_)) => {
454 Self::eat_token(tokenizer);
455 Ok(Node {
456 token: ParseToken::Filter(FilterToken::And),
457 left: Some(Box::new(prev)),
458 right: Some(Box::new(Self::exprs(tokenizer)?)),
459 })
460 }
461 Ok(Token::Or(_)) => {
462 Self::eat_token(tokenizer);
463 Ok(Node {
464 token: ParseToken::Filter(FilterToken::Or),
465 left: Some(Box::new(prev)),
466 right: Some(Box::new(Self::exprs(tokenizer)?)),
467 })
468 }
469 _ => Ok(prev),
470 }
471 }
472
473 fn expr(tokenizer: &mut TokenReader) -> ParseResult<Node> {
474 debug!("#expr");
475
476 let has_prop_candidate = matches!(tokenizer.peek_token(), Ok(Token::At(_)));
477
478 let node = Self::term(tokenizer)?;
479 Self::eat_whitespace(tokenizer);
480
481 if matches!(tokenizer.peek_token(),
482 Ok(Token::Equal(_))
483 | Ok(Token::NotEqual(_))
484 | Ok(Token::Little(_))
485 | Ok(Token::LittleOrEqual(_))
486 | Ok(Token::Greater(_))
487 | Ok(Token::GreaterOrEqual(_)))
488 {
489 Self::op(node, tokenizer)
490 } else if has_prop_candidate {
491 Ok(node)
492 } else {
493 Err(tokenizer.err_msg())
494 }
495 }
496
497 fn term_num(tokenizer: &mut TokenReader) -> ParseResult<Node> {
498 debug!("#term_num");
499 match tokenizer.next_token() {
500 Ok(Token::Key(pos, val)) => match tokenizer.peek_token() {
501 Ok(Token::Dot(_)) => Self::term_num_float(val.as_str(), tokenizer),
502 _ => {
503 let number = utils::string_to_num(&val, || tokenizer.err_msg_with_pos(pos))?;
504 Ok(Self::node(ParseToken::Number(number)))
505 }
506 },
507 _ => Err(tokenizer.err_msg()),
508 }
509 }
510
511 fn term_num_float(num: &str, tokenizer: &mut TokenReader) -> ParseResult<Node> {
512 debug!("#term_num_float");
513 Self::eat_token(tokenizer);
514 match tokenizer.next_token() {
515 Ok(Token::Key(pos, frac)) => {
516 let mut f = String::new();
517 f.push_str(&num);
518 f.push('.');
519 f.push_str(frac.as_str());
520 let number = utils::string_to_num(&f, || tokenizer.err_msg_with_pos(pos))?;
521 Ok(Self::node(ParseToken::Number(number)))
522 }
523 _ => Err(tokenizer.err_msg()),
524 }
525 }
526
527 fn term(tokenizer: &mut TokenReader) -> ParseResult<Node> {
528 debug!("#term");
529
530 match tokenizer.peek_token() {
531 Ok(Token::At(_)) => {
532 Self::eat_token(tokenizer);
533 let node = Self::node(ParseToken::Relative);
534
535 match tokenizer.peek_token() {
536 Ok(Token::Whitespace(_, _)) => {
537 Self::eat_whitespace(tokenizer);
538 Ok(node)
539 }
540 _ => Self::paths(node, tokenizer),
541 }
542 }
543 Ok(Token::Absolute(_)) => {
544 Self::json_path(tokenizer)
545 }
546 Ok(Token::DoubleQuoted(_, _)) | Ok(Token::SingleQuoted(_, _)) => {
547 Self::array_quote_value(tokenizer)
548 }
549 Ok(Token::Key(_, key)) => {
550 match key.as_bytes()[0] {
551 b'-' | b'0'..=b'9' => Self::term_num(tokenizer),
552 _ => Self::boolean(tokenizer),
553 }
554 }
555 _ => {
556 Err(tokenizer.err_msg())
557 }
558 }
559 }
560
561 fn op(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
562 debug!("#op");
563 let token = match tokenizer.next_token() {
564 Ok(Token::Equal(_)) => ParseToken::Filter(FilterToken::Equal),
565 Ok(Token::NotEqual(_)) => ParseToken::Filter(FilterToken::NotEqual),
566 Ok(Token::Little(_)) => ParseToken::Filter(FilterToken::Little),
567 Ok(Token::LittleOrEqual(_)) => ParseToken::Filter(FilterToken::LittleOrEqual),
568 Ok(Token::Greater(_)) => ParseToken::Filter(FilterToken::Greater),
569 Ok(Token::GreaterOrEqual(_)) => ParseToken::Filter(FilterToken::GreaterOrEqual),
570 _ => {
571 return Err(tokenizer.err_msg());
572 }
573 };
574
575 Self::eat_whitespace(tokenizer);
576
577 Ok(Node {
578 token,
579 left: Some(Box::new(prev)),
580 right: Some(Box::new(Self::term(tokenizer)?)),
581 })
582 }
583
584 fn eat_whitespace(tokenizer: &mut TokenReader) {
585 while let Ok(Token::Whitespace(_, _)) = tokenizer.peek_token() {
586 let _ = tokenizer.next_token();
587 }
588 }
589
590 fn eat_token(tokenizer: &mut TokenReader) {
591 let _ = tokenizer.next_token();
592 }
593
594 fn node(token: ParseToken) -> Node {
595 Node {
596 left: None,
597 right: None,
598 token,
599 }
600 }
601
602 fn close_token(ret: Node, token: Token, tokenizer: &mut TokenReader) -> ParseResult<Node> {
603 debug!("#close_token");
604 match tokenizer.next_token() {
605 Ok(ref t) if t.is_match_token_type(token) => Ok(ret),
606 _ => Err(tokenizer.err_msg()),
607 }
608 }
609}
610
611pub trait NodeVisitor {
612 fn visit(&mut self, node: &Node) {
613 match &node.token {
614 ParseToken::Absolute
615 | ParseToken::Relative
616 | ParseToken::All
617 | ParseToken::Key(_)
618 | ParseToken::Keys(_)
619 | ParseToken::Range(_, _, _)
620 | ParseToken::Union(_)
621 | ParseToken::Number(_)
622 | ParseToken::Bool(_) => {
623 self.visit_token(&node.token);
624 }
625 ParseToken::In | ParseToken::Leaves => {
626 if let Some(n) = &node.left {
627 self.visit(&*n);
628 }
629
630 self.visit_token(&node.token);
631
632 if let Some(n) = &node.right {
633 self.visit(&*n);
634 }
635 }
636 ParseToken::Array => {
637 if let Some(n) = &node.left {
638 self.visit(&*n);
639 }
640
641 self.visit_token(&node.token);
642
643 if let Some(n) = &node.right {
644 self.visit(&*n);
645 }
646
647 self.visit_token(&ParseToken::ArrayEof);
648 }
649 ParseToken::Filter(FilterToken::And) | ParseToken::Filter(FilterToken::Or) => {
650 if let Some(n) = &node.left {
651 self.visit(&*n);
652 }
653
654 if let Some(n) = &node.right {
655 self.visit(&*n);
656 }
657
658 self.visit_token(&node.token);
659 }
660 ParseToken::Filter(_) => {
661 if let Some(n) = &node.left {
662 self.visit(&*n);
663 }
664
665 self.end_term();
666
667 if let Some(n) = &node.right {
668 self.visit(&*n);
669 }
670
671 self.end_term();
672
673 self.visit_token(&node.token);
674 }
675 _ => {}
676 }
677 }
678
679 fn visit_token(&mut self, token: &ParseToken);
680 fn end_term(&mut self) {}
681}
682
683#[cfg(test)]
684mod parser_tests {
685 use parser::{FilterToken, NodeVisitor, ParseToken, Parser};
686
687 struct NodeVisitorTestImpl<'a> {
688 input: &'a str,
689 stack: Vec<ParseToken>,
690 }
691
692 impl<'a> NodeVisitorTestImpl<'a> {
693 fn new(input: &'a str) -> Self {
694 NodeVisitorTestImpl {
695 input,
696 stack: Vec::new(),
697 }
698 }
699
700 fn start(&mut self) -> Result<Vec<ParseToken>, String> {
701 let node = Parser::compile(self.input)?;
702 self.visit(&node);
703 Ok(self.stack.split_off(0))
704 }
705 }
706
707 impl<'a> NodeVisitor for NodeVisitorTestImpl<'a> {
708 fn visit_token(&mut self, token: &ParseToken) {
709 self.stack.push(token.clone());
710 }
711 }
712
713 fn setup() {
714 let _ = env_logger::try_init();
715 }
716
717 fn run(input: &str) -> Result<Vec<ParseToken>, String> {
718 let mut interpreter = NodeVisitorTestImpl::new(input);
719 interpreter.start()
720 }
721
722 #[test]
723 fn parse_error() {
724 setup();
725
726 fn invalid(path: &str) {
727 assert!(run(path).is_err());
728 }
729
730 invalid("$[]");
731 invalid("$[a]");
732 invalid("$[?($.a)]");
733 invalid("$[?(@.a > @.b]");
734 invalid("$[?(@.a < @.b&&(@.c < @.d)]");
735 invalid("@.");
736 invalid("$..[?(a <= @.a)]"); // invalid term value
737 invalid("$['a', b]");
738 invalid("$[0, >=]");
739 invalid("$[a:]");
740 invalid("$[:a]");
741 invalid("$[::a]");
742 invalid("$[:>]");
743 invalid("$[1:>]");
744 invalid("$[1,,]");
745 invalid("$[?]");
746 invalid("$[?(1 = 1)]");
747 invalid("$[?(1 = >)]");
748 }
749
750 #[test]
751 fn parse_path() {
752 setup();
753
754 assert_eq!(
755 run("$.aa"),
756 Ok(vec![
757 ParseToken::Absolute,
758 ParseToken::In,
759 ParseToken::Key("aa".to_owned())
760 ])
761 );
762
763 assert_eq!(
764 run("$.00.a"),
765 Ok(vec![
766 ParseToken::Absolute,
767 ParseToken::In,
768 ParseToken::Key("00".to_owned()),
769 ParseToken::In,
770 ParseToken::Key("a".to_owned())
771 ])
772 );
773
774 assert_eq!(
775 run("$.00.韓창.seok"),
776 Ok(vec![
777 ParseToken::Absolute,
778 ParseToken::In,
779 ParseToken::Key("00".to_owned()),
780 ParseToken::In,
781 ParseToken::Key("韓창".to_owned()),
782 ParseToken::In,
783 ParseToken::Key("seok".to_owned())
784 ])
785 );
786
787 assert_eq!(
788 run("$.*"),
789 Ok(vec![ParseToken::Absolute, ParseToken::In, ParseToken::All])
790 );
791
792 assert_eq!(
793 run("$..*"),
794 Ok(vec![
795 ParseToken::Absolute,
796 ParseToken::Leaves,
797 ParseToken::All
798 ])
799 );
800
801 assert_eq!(
802 run("$..[0]"),
803 Ok(vec![
804 ParseToken::Absolute,
805 ParseToken::Leaves,
806 ParseToken::Array,
807 ParseToken::Number(0.0),
808 ParseToken::ArrayEof
809 ])
810 );
811
812 assert_eq!(
813 run("$.$a"),
814 Ok(vec![
815 ParseToken::Absolute,
816 ParseToken::In,
817 ParseToken::Key("$a".to_owned())
818 ])
819 );
820
821 assert_eq!(
822 run("$.['$a']"),
823 Ok(vec![
824 ParseToken::Absolute,
825 ParseToken::Array,
826 ParseToken::Key("$a".to_owned()),
827 ParseToken::ArrayEof,
828 ])
829 );
830
831 if run("$.").is_ok() {
832 panic!();
833 }
834
835 if run("$..").is_ok() {
836 panic!();
837 }
838
839 if run("$. a").is_ok() {
840 panic!();
841 }
842 }
843
844 #[test]
845 fn parse_array_syntax() {
846 setup();
847
848 assert_eq!(
849 run("$.book[?(@.isbn)]"),
850 Ok(vec![
851 ParseToken::Absolute,
852 ParseToken::In,
853 ParseToken::Key("book".to_string()),
854 ParseToken::Array,
855 ParseToken::Relative,
856 ParseToken::In,
857 ParseToken::Key("isbn".to_string()),
858 ParseToken::ArrayEof
859 ])
860 );
861
862 //
863 // Array도 컨텍스트 In으로 간주 할거라서 중첩되면 하나만
864 //
865 assert_eq!(
866 run("$.[*]"),
867 Ok(vec![
868 ParseToken::Absolute,
869 ParseToken::Array,
870 ParseToken::All,
871 ParseToken::ArrayEof
872 ])
873 );
874
875 assert_eq!(
876 run("$.a[*]"),
877 Ok(vec![
878 ParseToken::Absolute,
879 ParseToken::In,
880 ParseToken::Key("a".to_owned()),
881 ParseToken::Array,
882 ParseToken::All,
883 ParseToken::ArrayEof
884 ])
885 );
886
887 assert_eq!(
888 run("$.a[*].가"),
889 Ok(vec![
890 ParseToken::Absolute,
891 ParseToken::In,
892 ParseToken::Key("a".to_owned()),
893 ParseToken::Array,
894 ParseToken::All,
895 ParseToken::ArrayEof,
896 ParseToken::In,
897 ParseToken::Key("가".to_owned())
898 ])
899 );
900
901 assert_eq!(
902 run("$.a[0][1]"),
903 Ok(vec![
904 ParseToken::Absolute,
905 ParseToken::In,
906 ParseToken::Key("a".to_owned()),
907 ParseToken::Array,
908 ParseToken::Number(0_f64),
909 ParseToken::ArrayEof,
910 ParseToken::Array,
911 ParseToken::Number(1_f64),
912 ParseToken::ArrayEof
913 ])
914 );
915
916 assert_eq!(
917 run("$.a[1,2]"),
918 Ok(vec![
919 ParseToken::Absolute,
920 ParseToken::In,
921 ParseToken::Key("a".to_owned()),
922 ParseToken::Array,
923 ParseToken::Union(vec![1, 2]),
924 ParseToken::ArrayEof
925 ])
926 );
927
928 assert_eq!(
929 run("$.a[10:]"),
930 Ok(vec![
931 ParseToken::Absolute,
932 ParseToken::In,
933 ParseToken::Key("a".to_owned()),
934 ParseToken::Array,
935 ParseToken::Range(Some(10), None, None),
936 ParseToken::ArrayEof
937 ])
938 );
939
940 assert_eq!(
941 run("$.a[:11]"),
942 Ok(vec![
943 ParseToken::Absolute,
944 ParseToken::In,
945 ParseToken::Key("a".to_owned()),
946 ParseToken::Array,
947 ParseToken::Range(None, Some(11), None),
948 ParseToken::ArrayEof
949 ])
950 );
951
952 assert_eq!(
953 run("$.a[-12:13]"),
954 Ok(vec![
955 ParseToken::Absolute,
956 ParseToken::In,
957 ParseToken::Key("a".to_owned()),
958 ParseToken::Array,
959 ParseToken::Range(Some(-12), Some(13), None),
960 ParseToken::ArrayEof
961 ])
962 );
963
964 assert_eq!(
965 run(r#"$[0:3:2]"#),
966 Ok(vec![
967 ParseToken::Absolute,
968 ParseToken::Array,
969 ParseToken::Range(Some(0), Some(3), Some(2)),
970 ParseToken::ArrayEof
971 ])
972 );
973
974 assert_eq!(
975 run(r#"$[:3:2]"#),
976 Ok(vec![
977 ParseToken::Absolute,
978 ParseToken::Array,
979 ParseToken::Range(None, Some(3), Some(2)),
980 ParseToken::ArrayEof
981 ])
982 );
983
984 assert_eq!(
985 run(r#"$[:]"#),
986 Ok(vec![
987 ParseToken::Absolute,
988 ParseToken::Array,
989 ParseToken::Range(None, None, None),
990 ParseToken::ArrayEof
991 ])
992 );
993
994 assert_eq!(
995 run(r#"$[::]"#),
996 Ok(vec![
997 ParseToken::Absolute,
998 ParseToken::Array,
999 ParseToken::Range(None, None, None),
1000 ParseToken::ArrayEof
1001 ])
1002 );
1003
1004 assert_eq!(
1005 run(r#"$[::2]"#),
1006 Ok(vec![
1007 ParseToken::Absolute,
1008 ParseToken::Array,
1009 ParseToken::Range(None, None, Some(2)),
1010 ParseToken::ArrayEof
1011 ])
1012 );
1013
1014 assert_eq!(
1015 run(r#"$["a", 'b']"#),
1016 Ok(vec![
1017 ParseToken::Absolute,
1018 ParseToken::Array,
1019 ParseToken::Keys(vec!["a".to_string(), "b".to_string()]),
1020 ParseToken::ArrayEof
1021 ])
1022 );
1023
1024 assert_eq!(
1025 run("$.a[?(1>2)]"),
1026 Ok(vec![
1027 ParseToken::Absolute,
1028 ParseToken::In,
1029 ParseToken::Key("a".to_owned()),
1030 ParseToken::Array,
1031 ParseToken::Number(1_f64),
1032 ParseToken::Number(2_f64),
1033 ParseToken::Filter(FilterToken::Greater),
1034 ParseToken::ArrayEof
1035 ])
1036 );
1037
1038 assert_eq!(
1039 run("$.a[?($.b>3)]"),
1040 Ok(vec![
1041 ParseToken::Absolute,
1042 ParseToken::In,
1043 ParseToken::Key("a".to_owned()),
1044 ParseToken::Array,
1045 ParseToken::Absolute,
1046 ParseToken::In,
1047 ParseToken::Key("b".to_owned()),
1048 ParseToken::Number(3_f64),
1049 ParseToken::Filter(FilterToken::Greater),
1050 ParseToken::ArrayEof
1051 ])
1052 );
1053
1054 assert_eq!(
1055 run("$[?($.c>@.d && 1==2)]"),
1056 Ok(vec![
1057 ParseToken::Absolute,
1058 ParseToken::Array,
1059 ParseToken::Absolute,
1060 ParseToken::In,
1061 ParseToken::Key("c".to_owned()),
1062 ParseToken::Relative,
1063 ParseToken::In,
1064 ParseToken::Key("d".to_owned()),
1065 ParseToken::Filter(FilterToken::Greater),
1066 ParseToken::Number(1_f64),
1067 ParseToken::Number(2_f64),
1068 ParseToken::Filter(FilterToken::Equal),
1069 ParseToken::Filter(FilterToken::And),
1070 ParseToken::ArrayEof
1071 ])
1072 );
1073
1074 assert_eq!(
1075 run("$[?($.c>@.d&&(1==2||3>=4))]"),
1076 Ok(vec![
1077 ParseToken::Absolute,
1078 ParseToken::Array,
1079 ParseToken::Absolute,
1080 ParseToken::In,
1081 ParseToken::Key("c".to_owned()),
1082 ParseToken::Relative,
1083 ParseToken::In,
1084 ParseToken::Key("d".to_owned()),
1085 ParseToken::Filter(FilterToken::Greater),
1086 ParseToken::Number(1_f64),
1087 ParseToken::Number(2_f64),
1088 ParseToken::Filter(FilterToken::Equal),
1089 ParseToken::Number(3_f64),
1090 ParseToken::Number(4_f64),
1091 ParseToken::Filter(FilterToken::GreaterOrEqual),
1092 ParseToken::Filter(FilterToken::Or),
1093 ParseToken::Filter(FilterToken::And),
1094 ParseToken::ArrayEof
1095 ])
1096 );
1097
1098 assert_eq!(
1099 run("$[?(@.a<@.b)]"),
1100 Ok(vec![
1101 ParseToken::Absolute,
1102 ParseToken::Array,
1103 ParseToken::Relative,
1104 ParseToken::In,
1105 ParseToken::Key("a".to_owned()),
1106 ParseToken::Relative,
1107 ParseToken::In,
1108 ParseToken::Key("b".to_owned()),
1109 ParseToken::Filter(FilterToken::Little),
1110 ParseToken::ArrayEof
1111 ])
1112 );
1113
1114 assert_eq!(
1115 run("$[*][*][*]"),
1116 Ok(vec![
1117 ParseToken::Absolute,
1118 ParseToken::Array,
1119 ParseToken::All,
1120 ParseToken::ArrayEof,
1121 ParseToken::Array,
1122 ParseToken::All,
1123 ParseToken::ArrayEof,
1124 ParseToken::Array,
1125 ParseToken::All,
1126 ParseToken::ArrayEof
1127 ])
1128 );
1129
1130 assert_eq!(
1131 run("$['a']['bb']"),
1132 Ok(vec![
1133 ParseToken::Absolute,
1134 ParseToken::Array,
1135 ParseToken::Key("a".to_string()),
1136 ParseToken::ArrayEof,
1137 ParseToken::Array,
1138 ParseToken::Key("bb".to_string()),
1139 ParseToken::ArrayEof
1140 ])
1141 );
1142
1143 assert_eq!(
1144 run("$.a[?(@.e==true)]"),
1145 Ok(vec![
1146 ParseToken::Absolute,
1147 ParseToken::In,
1148 ParseToken::Key("a".to_string()),
1149 ParseToken::Array,
1150 ParseToken::Relative,
1151 ParseToken::In,
1152 ParseToken::Key("e".to_string()),
1153 ParseToken::Bool(true),
1154 ParseToken::Filter(FilterToken::Equal),
1155 ParseToken::ArrayEof
1156 ])
1157 );
1158
1159 assert_eq!(
1160 run(r#"$[?(@ > 1)]"#),
1161 Ok(vec![
1162 ParseToken::Absolute,
1163 ParseToken::Array,
1164 ParseToken::Relative,
1165 ParseToken::Number(1_f64),
1166 ParseToken::Filter(FilterToken::Greater),
1167 ParseToken::ArrayEof
1168 ])
1169 );
1170
1171 assert_eq!(
1172 run("$[:]"),
1173 Ok(vec![
1174 ParseToken::Absolute,
1175 ParseToken::Array,
1176 ParseToken::Range(None, None, None),
1177 ParseToken::ArrayEof
1178 ])
1179 );
1180
1181 assert_eq!(
1182 run(r#"$['single\'quote']"#),
1183 Ok(vec![
1184 ParseToken::Absolute,
1185 ParseToken::Array,
1186 ParseToken::Key("single'quote".to_string()),
1187 ParseToken::ArrayEof
1188 ])
1189 );
1190
1191 assert_eq!(
1192 run(r#"$["single\"quote"]"#),
1193 Ok(vec![
1194 ParseToken::Absolute,
1195 ParseToken::Array,
1196 ParseToken::Key(r#"single"quote"#.to_string()),
1197 ParseToken::ArrayEof
1198 ])
1199 );
1200 }
1201
1202 #[test]
1203 fn parse_array_float() {
1204 setup();
1205
1206 assert_eq!(
1207 run("$[?(1.1<2.1)]"),
1208 Ok(vec![
1209 ParseToken::Absolute,
1210 ParseToken::Array,
1211 ParseToken::Number(1.1),
1212 ParseToken::Number(2.1),
1213 ParseToken::Filter(FilterToken::Little),
1214 ParseToken::ArrayEof
1215 ])
1216 );
1217
1218 if run("$[1.1]").is_ok() {
1219 panic!();
1220 }
1221
1222 if run("$[?(1.1<.2)]").is_ok() {
1223 panic!();
1224 }
1225
1226 if run("$[?(1.1<2.)]").is_ok() {
1227 panic!();
1228 }
1229
1230 if run("$[?(1.1<2.a)]").is_ok() {
1231 panic!();
1232 }
1233 }
1234}
1235
1236#[cfg(test)]
1237mod tokenizer_tests {
1238 use parser::tokenizer::{Token, TokenError, TokenReader, Tokenizer};
1239
1240 fn setup() {
1241 let _ = env_logger::try_init();
1242 }
1243
1244 fn collect_token(input: &str) -> (Vec<Token>, Option<TokenError>) {
1245 let mut tokenizer = Tokenizer::new(input);
1246 let mut vec = vec![];
1247 loop {
1248 match tokenizer.next_token() {
1249 Ok(t) => vec.push(t),
1250 Err(e) => return (vec, Some(e)),
1251 }
1252 }
1253 }
1254
1255 fn run(input: &str, expected: (Vec<Token>, Option<TokenError>)) {
1256 let (vec, err) = collect_token(input);
1257 assert_eq!((vec, err), expected, "\"{}\"", input);
1258 }
1259
1260 #[test]
1261 fn peek() {
1262 let mut tokenizer = TokenReader::new("$.a");
1263 match tokenizer.next_token() {
1264 Ok(t) => assert_eq!(Token::Absolute(0), t),
1265 _ => panic!(),
1266 }
1267
1268 match tokenizer.peek_token() {
1269 Ok(t) => assert_eq!(&Token::Dot(1), t),
1270 _ => panic!(),
1271 }
1272
1273 match tokenizer.peek_token() {
1274 Ok(t) => assert_eq!(&Token::Dot(1), t),
1275 _ => panic!(),
1276 }
1277
1278 match tokenizer.next_token() {
1279 Ok(t) => assert_eq!(Token::Dot(1), t),
1280 _ => panic!(),
1281 }
1282 }
1283
1284 #[test]
1285 fn token() {
1286 setup();
1287
1288 run(
1289 "$.01.a",
1290 (
1291 vec![
1292 Token::Absolute(0),
1293 Token::Dot(1),
1294 Token::Key(2, "01".to_string()),
1295 Token::Dot(4),
1296 Token::Key(5, "a".to_string()),
1297 ],
1298 Some(TokenError::Eof),
1299 ),
1300 );
1301
1302 run(
1303 "$. []",
1304 (
1305 vec![
1306 Token::Absolute(0),
1307 Token::Dot(1),
1308 Token::Whitespace(2, 2),
1309 Token::OpenArray(5),
1310 Token::CloseArray(6),
1311 ],
1312 Some(TokenError::Eof),
1313 ),
1314 );
1315
1316 run(
1317 "$..",
1318 (
1319 vec![Token::Absolute(0), Token::Dot(1), Token::Dot(2)],
1320 Some(TokenError::Eof),
1321 ),
1322 );
1323
1324 run(
1325 "$..ab",
1326 (
1327 vec![
1328 Token::Absolute(0),
1329 Token::Dot(1),
1330 Token::Dot(2),
1331 Token::Key(3, "ab".to_string()),
1332 ],
1333 Some(TokenError::Eof),
1334 ),
1335 );
1336
1337 run(
1338 "$..가 [",
1339 (
1340 vec![
1341 Token::Absolute(0),
1342 Token::Dot(1),
1343 Token::Dot(2),
1344 Token::Key(3, "가".to_string()),
1345 Token::Whitespace(6, 0),
1346 Token::OpenArray(7),
1347 ],
1348 Some(TokenError::Eof),
1349 ),
1350 );
1351
1352 run(
1353 "[-1, 2 ]",
1354 (
1355 vec![
1356 Token::OpenArray(0),
1357 Token::Key(1, "-1".to_string()),
1358 Token::Comma(3),
1359 Token::Whitespace(4, 0),
1360 Token::Key(5, "2".to_string()),
1361 Token::Whitespace(6, 0),
1362 Token::CloseArray(7),
1363 ],
1364 Some(TokenError::Eof),
1365 ),
1366 );
1367
1368 run(
1369 "[ 1 2 , 3 \"abc\" : -10 ]",
1370 (
1371 vec![
1372 Token::OpenArray(0),
1373 Token::Whitespace(1, 0),
1374 Token::Key(2, "1".to_string()),
1375 Token::Whitespace(3, 0),
1376 Token::Key(4, "2".to_string()),
1377 Token::Whitespace(5, 0),
1378 Token::Comma(6),
1379 Token::Whitespace(7, 0),
1380 Token::Key(8, "3".to_string()),
1381 Token::Whitespace(9, 0),
1382 Token::DoubleQuoted(10, "abc".to_string()),
1383 Token::Whitespace(15, 0),
1384 Token::Split(16),
1385 Token::Whitespace(17, 0),
1386 Token::Key(18, "-10".to_string()),
1387 Token::Whitespace(21, 0),
1388 Token::CloseArray(22),
1389 ],
1390 Some(TokenError::Eof),
1391 ),
1392 );
1393
1394 run(
1395 "?(@.a가 <41.01)",
1396 (
1397 vec![
1398 Token::Question(0),
1399 Token::OpenParenthesis(1),
1400 Token::At(2),
1401 Token::Dot(3),
1402 Token::Key(4, "a가".to_string()),
1403 Token::Whitespace(8, 0),
1404 Token::Little(9),
1405 Token::Key(10, "41".to_string()),
1406 Token::Dot(12),
1407 Token::Key(13, "01".to_string()),
1408 Token::CloseParenthesis(15),
1409 ],
1410 Some(TokenError::Eof),
1411 ),
1412 );
1413
1414 run(
1415 "?(@.a <4a.01)",
1416 (
1417 vec![
1418 Token::Question(0),
1419 Token::OpenParenthesis(1),
1420 Token::At(2),
1421 Token::Dot(3),
1422 Token::Key(4, "a".to_string()),
1423 Token::Whitespace(5, 0),
1424 Token::Little(6),
1425 Token::Key(7, "4a".to_string()),
1426 Token::Dot(9),
1427 Token::Key(10, "01".to_string()),
1428 Token::CloseParenthesis(12),
1429 ],
1430 Some(TokenError::Eof),
1431 ),
1432 );
1433
1434 run(
1435 "?($.c>@.d)",
1436 (
1437 vec![
1438 Token::Question(0),
1439 Token::OpenParenthesis(1),
1440 Token::Absolute(2),
1441 Token::Dot(3),
1442 Token::Key(4, "c".to_string()),
1443 Token::Greater(5),
1444 Token::At(6),
1445 Token::Dot(7),
1446 Token::Key(8, "d".to_string()),
1447 Token::CloseParenthesis(9),
1448 ],
1449 Some(TokenError::Eof),
1450 ),
1451 );
1452
1453 run(
1454 "$[:]",
1455 (
1456 vec![
1457 Token::Absolute(0),
1458 Token::OpenArray(1),
1459 Token::Split(2),
1460 Token::CloseArray(3),
1461 ],
1462 Some(TokenError::Eof),
1463 ),
1464 );
1465
1466 run(
1467 r#"$['single\'quote']"#,
1468 (
1469 vec![
1470 Token::Absolute(0),
1471 Token::OpenArray(1),
1472 Token::SingleQuoted(2, "single\'quote".to_string()),
1473 Token::CloseArray(17),
1474 ],
1475 Some(TokenError::Eof),
1476 ),
1477 );
1478
1479 run(
1480 r#"$['single\'1','single\'2']"#,
1481 (
1482 vec![
1483 Token::Absolute(0),
1484 Token::OpenArray(1),
1485 Token::SingleQuoted(2, "single\'1".to_string()),
1486 Token::Comma(13),
1487 Token::SingleQuoted(14, "single\'2".to_string()),
1488 Token::CloseArray(25),
1489 ],
1490 Some(TokenError::Eof),
1491 ),
1492 );
1493
1494 run(
1495 r#"$["double\"quote"]"#,
1496 (
1497 vec![
1498 Token::Absolute(0),
1499 Token::OpenArray(1),
1500 Token::DoubleQuoted(2, "double\"quote".to_string()),
1501 Token::CloseArray(17),
1502 ],
1503 Some(TokenError::Eof),
1504 ),
1505 );
1506 }
1507}
1508