1#[macro_export]
2macro_rules! gen_parser_to_node {
3 () => {
4 fn parse_to_node(code: &str) -> crate::ParserResult<Expr> {
5 let res = Self::parse(Rule::expression, &code)?.next().unwrap();
6 let res: crate::ast::expr::Expr = res.try_into()?;
7 Ok(res)
8 }
9 };
10}
11
12#[macro_export]
13macro_rules! gen_parser {
14 ($class_name:ident) => {
15 impl<'i> std::convert::TryFrom<pest::iterators::Pair<'i, Rule>>
16 for crate::ast::comparison::Comparison
17 {
18 type Error = crate::error::ParserError;
19
20 fn try_from(
21 value: pest::iterators::Pair<Rule>,
22 ) -> std::result::Result<Self, Self::Error> {
23 match value.as_rule() {
24 Rule::comparison => {
25 let comp_name = value.as_str();
26 if let Some(&comp) = $class_name::default_comparisons().get(comp_name) {
27 Ok(comp.clone())
28 } else {
29 Err(crate::error::ParserError::InvalidComparison(comp_name.to_string()))
30 }
31 },
32 _ => crate::error::ParserError::invalid_pair_rule()?,
33 }
34 }
35 }
36
37 impl<'i> std::convert::TryFrom<pest::iterators::Pair<'i, Rule>>
38 for crate::ast::constraint::Constraint
39 {
40 type Error = crate::error::ParserError;
41
42 fn try_from(
43 value: pest::iterators::Pair<'i, Rule>,
44 ) -> std::result::Result<Self, Self::Error> {
45 let mut selector_opt: std::option::Option<String> = None;
46 let mut comparison_opt: std::option::Option<Comparison> = None;
47 let mut arguments_opt: std::option::Option<Arguments> = None;
48
49 match value.as_rule() {
50 Rule::constraint => {
51 for item in value.into_inner() {
52 match item.as_rule() {
53 Rule::selector => selector_opt = Some(item.as_str().to_string()),
54 Rule::comparison => comparison_opt = item.try_into().ok(),
55 Rule::argument => arguments_opt = item.try_into().ok(),
56 _ => {},
57 }
58 }
59 let selector = if let Some(selector) = selector_opt {
60 selector
61 } else {
62 return Err(ParserError::LackOfField {
63 ty: "Constraint".to_string(),
64 field: "selector".to_string(),
65 });
66 };
67 let comparison = if let Some(comparison) = comparison_opt {
68 comparison
69 } else {
70 return Err(ParserError::LackOfField {
71 ty: "Constraint".to_string(),
72 field: "comparison".to_string(),
73 });
74 };
75 let arguments = if let Some(arguments) = arguments_opt {
76 arguments
77 } else {
78 return Err(ParserError::LackOfField {
79 ty: "Constraint".to_string(),
80 field: "arguments".to_string(),
81 });
82 };
83
84 Ok(crate::ast::constraint::Constraint { selector, comparison, arguments })
85 },
86 _ => crate::error::ParserError::invalid_pair_rule()?,
87 }
88 }
89 }
90
91 impl<'i> std::convert::TryFrom<pest::iterators::Pair<'i, Rule>> for crate::ast::Operator {
92 type Error = crate::error::ParserError;
93
94 fn try_from(
95 value: pest::iterators::Pair<'i, Rule>,
96 ) -> std::result::Result<Self, Self::Error> {
97 match value.as_rule() {
98 Rule::operator => match value.into_inner().next() {
99 Some(pair) if pair.as_rule() == Rule::and_op => {
100 Ok(crate::ast::Operator::And)
101 },
102 Some(pair) if pair.as_rule() == Rule::or_op => Ok(crate::ast::Operator::Or),
103 _ => ParserError::invalid_pair_rule()?,
104 },
105 _ => ParserError::invalid_pair_rule()?,
106 }
107 }
108 }
109
110 impl<'i> std::convert::TryFrom<pest::iterators::Pair<'i, Rule>> for crate::ast::expr::Expr {
111 type Error = crate::error::ParserError;
112
113 fn try_from(
114 value: pest::iterators::Pair<'i, Rule>,
115 ) -> std::result::Result<Self, Self::Error> {
116 let mut op_vec: std::vec::Vec<crate::ast::Operator> = vec![];
117 let mut expr_vec: std::vec::Vec<Expr> = vec![];
118
119 let mut parse_op =
120 |pair: pest::iterators::Pair<'i, Rule>| -> crate::ParserResult<()> {
121 match pair.as_rule() {
122 Rule::operator if vec![";", "and"].contains(&pair.as_str()) => {
123 op_vec.push(crate::ast::Operator::And)
124 },
125 Rule::operator if vec![",", "or"].contains(&pair.as_str()) => {
126 op_vec.push(crate::ast::Operator::Or)
127 },
128 _ => crate::error::ParserError::invalid_pair_rule()?,
129 }
130 Ok(())
131 };
132
133 match value.as_rule() {
134 Rule::expression => {
135 for expr_item in value.into_inner() {
136 match expr_item.as_rule() {
137 Rule::constraint => {
138 expr_vec.push(Expr::Item(expr_item.try_into()?))
139 },
140 Rule::group => expr_vec.push(Expr::try_from(expr_item)?),
141 Rule::operator => parse_op(expr_item)?,
142 _ => crate::error::ParserError::invalid_pair_rule()?,
143 }
144 }
145 },
146 Rule::group => {
147 for group_item in value.into_inner() {
148 match group_item.as_rule() {
149 Rule::expression => expr_vec.push(Expr::try_from(group_item)?),
150 Rule::operator => parse_op(group_item)?,
151 _ => crate::error::ParserError::invalid_pair_rule()?,
152 }
153 }
154 },
155 _ => crate::error::ParserError::invalid_pair_rule()?,
156 }
157
158 while let Some(top_op) = op_vec.pop() {
159 if expr_vec.len() < 2 {
160 crate::error::ParserError::invalid_pair_rule()?
161 } else {
162 let right = expr_vec.pop().unwrap();
163 let left = expr_vec.pop().unwrap();
164 expr_vec.push(crate::ast::expr::Expr::Node(
165 top_op,
166 Box::new(left),
167 Box::new(right),
168 ));
169 }
170 }
171
172 if op_vec.is_empty() && expr_vec.len() == 1 {
173 Ok(expr_vec.pop().unwrap())
174 } else {
175 crate::error::ParserError::invalid_pair_rule()?
176 }
177 }
178 }
179 };
180}