|
4 | 4 | * SPDX-License-Identifier: BSD-2-Clause
|
5 | 5 | */
|
6 | 6 |
|
7 |
| -use crate::matchers; |
8 |
| -use crate::path; |
| 7 | +pub use crate::ast::*; |
9 | 8 | use crate::pest::Parser;
|
10 | 9 |
|
11 | 10 | #[derive(Parser)]
|
12 | 11 | #[grammar = "grammar.pest"]
|
13 | 12 | struct PathParser;
|
14 | 13 |
|
15 |
| -pub fn parse(selector: &str) -> Result<impl path::Path, String> { |
| 14 | +pub fn parse(selector: &str) -> Result<Path, String> { |
16 | 15 | let selector_rule = PathParser::parse(Rule::selector, selector)
|
17 | 16 | .map_err(|e| format!("{}", e))?
|
18 | 17 | .next()
|
19 | 18 | .unwrap();
|
20 | 19 |
|
21 |
| - let mut ms: Vec<Box<dyn matchers::Matcher>> = Vec::new(); |
| 20 | + let mut res = Path::Root; |
22 | 21 | for r in selector_rule.into_inner() {
|
23 |
| - match r.as_rule() { |
24 |
| - Rule::rootSelector => ms.push(Box::new(matchers::RootSelector {})), |
25 |
| - |
26 |
| - Rule::matcher => { |
27 |
| - for m in parse_matcher(r) { |
28 |
| - ms.push(m) |
29 |
| - } |
30 |
| - } |
31 |
| - |
32 |
| - _ => println!("r={:?}", r), |
| 22 | + res = match r.as_rule() { |
| 23 | + Rule::rootSelector => res, // TODO: fix grammar so that this is a silent rule since we don't need it |
| 24 | + Rule::matcher => Path::Sel(Box::new(res), parse_selector(r)), |
| 25 | + _ => panic!("invalid parse tree {:?}", r), |
33 | 26 | }
|
34 | 27 | }
|
35 |
| - |
36 |
| - Ok(path::new(ms)) |
| 28 | + Ok(res) |
37 | 29 | }
|
38 | 30 |
|
39 |
| -fn parse_matcher(matcher_rule: pest::iterators::Pair<Rule>) -> Vec<Box<dyn matchers::Matcher>> { |
40 |
| - let mut ms: Vec<Box<dyn matchers::Matcher>> = Vec::new(); |
41 |
| - for r in matcher_rule.into_inner() { |
42 |
| - match r.as_rule() { |
43 |
| - Rule::wildcardedDotChild => ms.push(Box::new(matchers::WildcardedChild {})), |
44 |
| - |
45 |
| - Rule::namedDotChild => { |
46 |
| - for m in parse_dot_child_matcher(r) { |
47 |
| - ms.push(m) |
48 |
| - } |
49 |
| - } |
50 |
| - |
51 |
| - Rule::union => { |
52 |
| - for m in parse_union(r) { |
53 |
| - ms.push(m) |
54 |
| - } |
55 |
| - } |
| 31 | +fn parse_selector(matcher_rule: pest::iterators::Pair<Rule>) -> Selector { |
| 32 | + let r = matcher_rule.into_inner().next().unwrap(); |
56 | 33 |
|
57 |
| - _ => (), |
58 |
| - } |
| 34 | + match r.as_rule() { |
| 35 | + Rule::wildcardedDotChild => Selector::DotWildcard, |
| 36 | + Rule::namedDotChild => Selector::DotName(parse_child_name(r)), |
| 37 | + Rule::union => Selector::Union(parse_union_indices(r)), |
| 38 | + _ => panic!("invalid parse tree {:?}", r), |
59 | 39 | }
|
60 |
| - ms |
61 | 40 | }
|
62 | 41 |
|
63 |
| -fn parse_dot_child_matcher( |
64 |
| - matcher_rule: pest::iterators::Pair<Rule>, |
65 |
| -) -> Vec<Box<dyn matchers::Matcher>> { |
66 |
| - let mut ms: Vec<Box<dyn matchers::Matcher>> = Vec::new(); |
67 |
| - for r in matcher_rule.into_inner() { |
68 |
| - if let Rule::childName = r.as_rule() { |
69 |
| - ms.push(Box::new(matchers::Child::new(r.as_str().to_owned()))); |
70 |
| - } |
| 42 | +fn parse_child_name(matcher_rule: pest::iterators::Pair<Rule>) -> String { |
| 43 | + let r = matcher_rule.into_inner().next().unwrap(); |
| 44 | + match r.as_rule() { |
| 45 | + Rule::childName => r.as_str().to_owned(), |
| 46 | + _ => panic!("invalid parse tree {:?}", r), |
71 | 47 | }
|
72 |
| - ms |
73 | 48 | }
|
74 | 49 |
|
75 |
| -fn parse_union(matcher_rule: pest::iterators::Pair<Rule>) -> Vec<Box<dyn matchers::Matcher>> { |
76 |
| - let mut ms: Vec<Box<dyn matchers::Matcher>> = Vec::new(); |
| 50 | +fn parse_union_indices(matcher_rule: pest::iterators::Pair<Rule>) -> Vec<Index> { |
| 51 | + let mut res = Vec::new(); |
| 52 | + |
77 | 53 | for r in matcher_rule.into_inner() {
|
78 | 54 | match r.as_rule() {
|
79 |
| - Rule::unionChild => { |
80 |
| - for m in parse_union_child(r) { |
81 |
| - ms.push(m) |
82 |
| - } |
83 |
| - } |
84 |
| - Rule::unionArrayIndex => { |
85 |
| - for m in parse_union_array_index(r) { |
86 |
| - ms.push(m) |
87 |
| - } |
88 |
| - } |
89 |
| - _ => {} |
| 55 | + Rule::unionChild => res.append(&mut parse_union_child(r)), |
| 56 | + Rule::unionArrayIndex => res.push(parse_union_array_index(r)), |
| 57 | + _ => panic!("invalid parse tree {:?}", r), |
90 | 58 | }
|
91 | 59 | }
|
92 |
| - vec![Box::new(matchers::Union::new(ms))] |
| 60 | + res |
93 | 61 | }
|
94 | 62 |
|
95 |
| -fn parse_union_child(matcher_rule: pest::iterators::Pair<Rule>) -> Vec<Box<dyn matchers::Matcher>> { |
96 |
| - let mut ms: Vec<Box<dyn matchers::Matcher>> = Vec::new(); |
| 63 | +fn parse_union_child(matcher_rule: pest::iterators::Pair<Rule>) -> Vec<Index> { |
| 64 | + let mut res = Vec::new(); |
97 | 65 | for r in matcher_rule.into_inner() {
|
98 | 66 | match r.as_rule() {
|
99 |
| - Rule::doubleInner => { |
100 |
| - ms.push(Box::new(matchers::Child::new(unescape(r.as_str())))); |
101 |
| - } |
102 |
| - |
103 |
| - Rule::singleInner => { |
104 |
| - ms.push(Box::new(matchers::Child::new(unescape_single(r.as_str())))); |
105 |
| - } |
106 |
| - |
107 |
| - _ => (), |
| 67 | + Rule::doubleInner => res.push(Index::Field(unescape(r.as_str()))), |
| 68 | + Rule::singleInner => res.push(Index::Field(unescape_single(r.as_str()))), |
| 69 | + _ => panic!("invalid parse tree {:?}", r), |
108 | 70 | }
|
109 | 71 | }
|
110 |
| - ms |
| 72 | + res |
111 | 73 | }
|
112 | 74 |
|
113 |
| -fn parse_union_array_index( |
114 |
| - matcher_rule: pest::iterators::Pair<Rule>, |
115 |
| -) -> Vec<Box<dyn matchers::Matcher>> { |
116 |
| - let mut ms: Vec<Box<dyn matchers::Matcher>> = Vec::new(); |
| 75 | +fn parse_union_array_index(matcher_rule: pest::iterators::Pair<Rule>) -> Index { |
117 | 76 | let i = matcher_rule.as_str().parse().unwrap();
|
118 |
| - ms.push(Box::new(matchers::ArrayIndex::new(i))); |
119 |
| - ms |
| 77 | + Index::Number(i) |
120 | 78 | }
|
121 | 79 |
|
122 | 80 | fn unescape(contents: &str) -> String {
|
|
0 commit comments