dynparser/parser/expression/
mod.rs1#![warn(missing_docs)]
2use super::super::idata::{
5 cont::IVec,
6 tc::{tail_call, TailCall},
7};
8use ast;
9use parser::{atom, atom::Atom, ErrPriority, Error, Result, Status};
10use std::collections::HashMap;
11use std::result;
12
13#[cfg(test)]
14mod test;
15
16#[derive(Clone, Copy, Debug)]
25pub(crate) struct Started(usize);
26
27pub(crate) type ResultExpr<'a> = result::Result<(Status<'a>, Vec<ast::Node>), Error>;
28
29#[derive(Debug)]
34pub struct SetOfRules(pub(crate) HashMap<String, Expression>);
35
36impl SetOfRules {
37 pub fn new(mrules: HashMap<String, Expression>) -> Self {
40 SetOfRules(mrules)
41 }
42
43 pub fn add(mut self, name: &str, expr: Expression) -> Self {
71 self.0.insert(name.to_owned(), expr);
72 self
73 }
74
75 pub fn merge(self, rules2merge: Self) -> Self {
103 SetOfRules(rules2merge.0.into_iter().chain(self.0).collect())
104 }
105}
106
107#[allow(missing_docs)]
108#[derive(Debug)]
109pub enum Expression {
110 Simple(Atom),
111 And(MultiExpr),
112 Or(MultiExpr),
113 Not(Box<Expression>),
114 Repeat(RepInfo),
115 RuleName(String),
116}
117
118#[derive(Debug)]
120pub struct MultiExpr(pub(crate) Vec<Expression>);
121
122impl MultiExpr {
123 pub fn new(v: Vec<Expression>) -> Self {
125 MultiExpr(v)
126 }
127}
128
129#[derive(Debug)]
131pub struct RepInfo {
132 pub(crate) expression: Box<Expression>,
133 pub(crate) min: NRep,
134 pub(crate) max: Option<NRep>,
135}
136
137impl RepInfo {
138 pub fn new(expression: Box<Expression>, min: usize, max: Option<usize>) -> Self {
141 RepInfo {
142 expression,
143 min: NRep(min),
144 max: max.map(NRep),
145 }
146 }
147}
148
149#[derive(Debug)]
151pub(crate) struct NRep(pub(crate) usize);
152
153pub(crate) fn parse(status: Status) -> Result {
163 parse_rule_name(status, "main")
164}
165
166fn parse_rule_name<'a>(status: Status<'a>, rule_name: &str) -> Result<'a> {
171 let status = if status.trace_rules {
175 status.push_rule(&format!("r:{}", rule_name))
176 } else {
177 status
178 };
179
180 let rules = &status.rules.0;
181 let expression = rules.get(rule_name).ok_or_else(|| {
182 Error::from_status(
183 &status,
184 &format!("Missing rule: {}", rule_name),
185 ErrPriority::Critical,
186 )
187 })?;
188 let (st, nodes) = parse_expr(status, &expression)?;
189
190 Ok((st, ast::Node::Rule((rule_name.to_owned(), nodes))))
198}
199
200fn parse_atom_as_expr<'a>(status: Status<'a>, a: &'a Atom) -> ResultExpr<'a> {
201 let (st, node) = atom::parse(status, a)?;
202 Ok((st, vec![node]))
203}
204
205fn parse_rule_name_as_expr<'a>(status: Status<'a>, rule_name: &str) -> ResultExpr<'a> {
206 let (st, ast) = parse_rule_name(status, rule_name)?;
207 Ok((st, vec![ast]))
208}
209
210fn parse_expr<'a>(status: Status<'a>, expression: &'a Expression) -> ResultExpr<'a> {
211 match *expression {
212 Expression::Simple(ref val) => parse_atom_as_expr(status, &val),
213 Expression::And(ref val) => parse_and(status, &val),
214 Expression::Or(ref val) => parse_or(&status, &val),
215 Expression::Not(ref val) => parse_not(status, &val),
216 Expression::Repeat(ref val) => parse_repeat(status, &val),
217 Expression::RuleName(ref val) => parse_rule_name_as_expr(status, &val),
218 }
219}
220
221fn parse_and<'a>(status: Status<'a>, multi_expr: &'a MultiExpr) -> ResultExpr<'a> {
223 let init_tc: (_, &[Expression], Vec<ast::Node>) = (status, &(multi_expr.0), vec![]);
224
225 tail_call(init_tc, |acc| {
226 if acc.1.is_empty() {
227 TailCall::Return(Ok((acc.0, acc.2)))
228 } else {
229 let result_parse = parse_expr(acc.0, &acc.1[0]);
230 match result_parse {
231 Ok((status, vnodes)) => {
232 TailCall::Call((status, &acc.1[1..], acc.2.iappend(vnodes)))
233 }
234 Err(err) => TailCall::Return(Err(err)),
235 }
236 }
237 })
238}
239
240fn parse_or<'a>(status: &Status<'a>, multi_expr: &'a MultiExpr) -> ResultExpr<'a> {
242 let deep_err = |oe1: Option<Error>, e2: Error| match oe1 {
243 Some(e1) => match (e1.priority > e2.priority, e1.pos.n > e2.pos.n) {
244 (true, _) => Some(e1),
245 (false, true) => Some(e1),
246 (false, false) => Some(e2),
247 },
248 None => Some(e2),
249 };
250
251 let init_tc: (_, &[Expression], _) = (status.clone(), &(multi_expr.0), None);
253
254 tail_call(init_tc, |acc| {
255 if acc.1.is_empty() {
256 TailCall::Return(Err(match acc.2 {
257 Some(err) => err,
258 _ => Error::from_st_errs(
259 &status,
260 "LOGIC ERROR!!! checked all options in or with ¿NO? errors",
261 vec![],
262 ),
263 }))
264 } else {
265 let try_parse = parse_expr(acc.0.clone(), &acc.1[0]);
266 match try_parse {
267 Ok(result) => TailCall::Return(Ok(result)),
268 Err(e) => {
269 if e.priority == ErrPriority::Critical {
270 TailCall::Return(Err(e))
271 } else {
272 TailCall::Call((acc.0, &acc.1[1..], deep_err(acc.2, e)))
273 }
274 }
275 }
276 }
277 })
278}
279
280fn parse_not<'a>(status: Status<'a>, expression: &'a Expression) -> ResultExpr<'a> {
282 match parse_expr(status.clone(), expression) {
283 Ok(_) => Err(Error::from_status_normal(&status, "not")),
284 Err(_) => Ok((status, vec![])),
285 }
286}
287
288fn parse_repeat<'a>(status: Status<'a>, rep_info: &'a RepInfo) -> ResultExpr<'a> {
290 let big_min_bound = |counter| counter >= rep_info.min.0;
291 let touch_max_bound = |counter: usize| match rep_info.max {
292 Some(ref m) => counter + 1 == m.0,
293 None => false,
294 };
295
296 let init_tc: (_, _, Vec<ast::Node>) = (status, 0, vec![]);
297 Ok(tail_call(init_tc, |acc| {
298 let try_parse = parse_expr(acc.0.clone(), &rep_info.expression);
299 match (try_parse, big_min_bound(acc.1), touch_max_bound(acc.1)) {
300 (Err(e), true, _) => if e.priority == ErrPriority::Critical {
301 TailCall::Return(Err(e))
302 } else {
303 TailCall::Return(Ok((acc.0.set_potential_error(e), acc.2)))
304 },
305 (Err(e), false, _) => TailCall::Return(Err(e)),
306 (Ok((status, vnodes)), _, false) => {
311 TailCall::Call((status, acc.1 + 1, acc.2.iappend(vnodes)))
312 }
313 (Ok((status, vnodes)), _, true) => {
314 TailCall::Return(Ok((status, acc.2.iappend(vnodes))))
315 }
316 }
317 })?)
318}
319