1#[derive(Clone, Debug, Eq, PartialEq)]
14pub struct Rule {
15 pub name: String,
17 pub ty: RuleType,
19 pub expr: Expr,
21}
22
23#[derive(Clone, Copy, Debug, Eq, PartialEq)]
25pub enum RuleType {
26 Normal,
28 Silent,
34 Atomic,
42 CompoundAtomic,
46 NonAtomic,
49}
50
51#[derive(Clone, Debug, Eq, PartialEq)]
60pub enum Expr {
61 Str(String),
63 Insens(String),
65 Range(String, String),
67 Ident(String),
69 PeekSlice(i32, Option<i32>),
71 PosPred(Box<Expr>),
73 NegPred(Box<Expr>),
75 Seq(Box<Expr>, Box<Expr>),
77 Choice(Box<Expr>, Box<Expr>),
79 Opt(Box<Expr>),
81 Rep(Box<Expr>),
83 RepOnce(Box<Expr>),
85 RepExact(Box<Expr>, u32),
87 RepMin(Box<Expr>, u32),
89 RepMax(Box<Expr>, u32),
91 RepMinMax(Box<Expr>, u32, u32),
93 Skip(Vec<String>),
95 Push(Box<Expr>),
97 #[cfg(feature = "grammar-extras")]
99 NodeTag(Box<Expr>, String),
100}
101
102impl Expr {
103 pub fn iter_top_down(&self) -> ExprTopDownIterator {
105 ExprTopDownIterator::new(self)
106 }
107
108 pub fn map_top_down<F>(self, mut f: F) -> Expr
110 where
111 F: FnMut(Expr) -> Expr,
112 {
113 fn map_internal<F>(expr: Expr, f: &mut F) -> Expr
114 where
115 F: FnMut(Expr) -> Expr,
116 {
117 let expr = f(expr);
118
119 match expr {
120 Expr::PosPred(expr) => {
121 let mapped = Box::new(map_internal(*expr, f));
122 Expr::PosPred(mapped)
123 }
124 Expr::NegPred(expr) => {
125 let mapped = Box::new(map_internal(*expr, f));
126 Expr::NegPred(mapped)
127 }
128 Expr::Seq(lhs, rhs) => {
129 let mapped_lhs = Box::new(map_internal(*lhs, f));
130 let mapped_rhs = Box::new(map_internal(*rhs, f));
131 Expr::Seq(mapped_lhs, mapped_rhs)
132 }
133 Expr::Choice(lhs, rhs) => {
134 let mapped_lhs = Box::new(map_internal(*lhs, f));
135 let mapped_rhs = Box::new(map_internal(*rhs, f));
136 Expr::Choice(mapped_lhs, mapped_rhs)
137 }
138 Expr::Rep(expr) => {
139 let mapped = Box::new(map_internal(*expr, f));
140 Expr::Rep(mapped)
141 }
142 Expr::RepOnce(expr) => {
143 let mapped = Box::new(map_internal(*expr, f));
144 Expr::RepOnce(mapped)
145 }
146 Expr::RepExact(expr, max) => {
147 let mapped = Box::new(map_internal(*expr, f));
148 Expr::RepExact(mapped, max)
149 }
150 Expr::RepMin(expr, num) => {
151 let mapped = Box::new(map_internal(*expr, f));
152 Expr::RepMin(mapped, num)
153 }
154 Expr::RepMax(expr, num) => {
155 let mapped = Box::new(map_internal(*expr, f));
156 Expr::RepMax(mapped, num)
157 }
158 Expr::RepMinMax(expr, min, max) => {
159 let mapped = Box::new(map_internal(*expr, f));
160 Expr::RepMinMax(mapped, min, max)
161 }
162 Expr::Opt(expr) => {
163 let mapped = Box::new(map_internal(*expr, f));
164 Expr::Opt(mapped)
165 }
166 Expr::Push(expr) => {
167 let mapped = Box::new(map_internal(*expr, f));
168 Expr::Push(mapped)
169 }
170 #[cfg(feature = "grammar-extras")]
171 Expr::NodeTag(expr, tag) => {
172 let mapped = Box::new(map_internal(*expr, f));
173 Expr::NodeTag(mapped, tag)
174 }
175 expr => expr,
176 }
177 }
178
179 map_internal(self, &mut f)
180 }
181
182 pub fn map_bottom_up<F>(self, mut f: F) -> Expr
184 where
185 F: FnMut(Expr) -> Expr,
186 {
187 fn map_internal<F>(expr: Expr, f: &mut F) -> Expr
188 where
189 F: FnMut(Expr) -> Expr,
190 {
191 let mapped = match expr {
192 Expr::PosPred(expr) => {
193 let mapped = Box::new(map_internal(*expr, f));
194 Expr::PosPred(mapped)
195 }
196 Expr::NegPred(expr) => {
197 let mapped = Box::new(map_internal(*expr, f));
198 Expr::NegPred(mapped)
199 }
200 Expr::Seq(lhs, rhs) => {
201 let mapped_lhs = Box::new(map_internal(*lhs, f));
202 let mapped_rhs = Box::new(map_internal(*rhs, f));
203 Expr::Seq(mapped_lhs, mapped_rhs)
204 }
205 Expr::Choice(lhs, rhs) => {
206 let mapped_lhs = Box::new(map_internal(*lhs, f));
207 let mapped_rhs = Box::new(map_internal(*rhs, f));
208 Expr::Choice(mapped_lhs, mapped_rhs)
209 }
210 Expr::Rep(expr) => {
211 let mapped = Box::new(map_internal(*expr, f));
212 Expr::Rep(mapped)
213 }
214 Expr::RepOnce(expr) => {
215 let mapped = Box::new(map_internal(*expr, f));
216 Expr::RepOnce(mapped)
217 }
218 Expr::RepExact(expr, num) => {
219 let mapped = Box::new(map_internal(*expr, f));
220 Expr::RepExact(mapped, num)
221 }
222 Expr::RepMin(expr, max) => {
223 let mapped = Box::new(map_internal(*expr, f));
224 Expr::RepMin(mapped, max)
225 }
226 Expr::RepMax(expr, max) => {
227 let mapped = Box::new(map_internal(*expr, f));
228 Expr::RepMax(mapped, max)
229 }
230 Expr::RepMinMax(expr, min, max) => {
231 let mapped = Box::new(map_internal(*expr, f));
232 Expr::RepMinMax(mapped, min, max)
233 }
234 Expr::Opt(expr) => {
235 let mapped = Box::new(map_internal(*expr, f));
236 Expr::Opt(mapped)
237 }
238 Expr::Push(expr) => {
239 let mapped = Box::new(map_internal(*expr, f));
240 Expr::Push(mapped)
241 }
242 #[cfg(feature = "grammar-extras")]
243 Expr::NodeTag(expr, tag) => {
244 let mapped = Box::new(map_internal(*expr, f));
245 Expr::NodeTag(mapped, tag)
246 }
247 expr => expr,
248 };
249
250 f(mapped)
251 }
252
253 map_internal(self, &mut f)
254 }
255}
256
257impl core::fmt::Display for Expr {
258 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
259 match self {
260 Expr::Str(s) => write!(f, "{:?}", s),
261 Expr::Insens(s) => write!(f, "^{:?}", s),
262 Expr::Range(start, end) => {
263 let start = start.chars().next().expect("Empty range start.");
264 let end = end.chars().next().expect("Empty range end.");
265 write!(f, "({:?}..{:?})", start, end)
266 }
267 Expr::Ident(id) => write!(f, "{}", id),
268 Expr::PeekSlice(start, end) => match end {
269 Some(end) => write!(f, "PEEK[{}..{}]", start, end),
270 None => write!(f, "PEEK[{}..]", start),
271 },
272 Expr::PosPred(expr) => write!(f, "&{}", expr.as_ref()),
273 Expr::NegPred(expr) => write!(f, "!{}", expr.as_ref()),
274 Expr::Seq(lhs, rhs) => {
275 let mut nodes = Vec::new();
276 nodes.push(lhs);
277 let mut current = rhs;
278 while let Expr::Seq(lhs, rhs) = current.as_ref() {
279 nodes.push(lhs);
280 current = rhs;
281 }
282 nodes.push(current);
283 let sequence = nodes
284 .iter()
285 .map(|node| format!("{}", node))
286 .collect::<Vec<_>>()
287 .join(" ~ ");
288 write!(f, "({})", sequence)
289 }
290 Expr::Choice(lhs, rhs) => {
291 let mut nodes = Vec::new();
292 nodes.push(lhs);
293 let mut current = rhs;
294 while let Expr::Choice(lhs, rhs) = current.as_ref() {
295 nodes.push(lhs);
296 current = rhs;
297 }
298 nodes.push(current);
299 let sequence = nodes
300 .iter()
301 .map(|node| format!("{}", node))
302 .collect::<Vec<_>>()
303 .join(" | ");
304 write!(f, "({})", sequence)
305 }
306 Expr::Opt(expr) => write!(f, "{}?", expr),
307 Expr::Rep(expr) => write!(f, "{}*", expr),
308 Expr::RepOnce(expr) => write!(f, "{}+", expr),
309 Expr::RepExact(expr, n) => write!(f, "{}{{{}}}", expr, n),
310 Expr::RepMin(expr, min) => write!(f, "{}{{{},}}", expr, min),
311 Expr::RepMax(expr, max) => write!(f, "{}{{,{}}}", expr, max),
312 Expr::RepMinMax(expr, min, max) => write!(f, "{}{{{}, {}}}", expr, min, max),
313 Expr::Skip(strings) => {
314 let strings = strings
315 .iter()
316 .map(|s| format!("{:?}", s))
317 .collect::<Vec<_>>()
318 .join(" | ");
319 write!(f, "(!({}) ~ ANY)*", strings)
320 }
321 Expr::Push(expr) => write!(f, "PUSH({})", expr),
322 #[cfg(feature = "grammar-extras")]
323 Expr::NodeTag(expr, tag) => {
324 write!(f, "(#{} = {})", tag, expr)
325 }
326 }
327 }
328}
329
330pub struct ExprTopDownIterator {
332 current: Option<Expr>,
333 next: Option<Expr>,
334 right_branches: Vec<Expr>,
335}
336
337impl ExprTopDownIterator {
338 pub fn new(expr: &Expr) -> Self {
340 let mut iter = ExprTopDownIterator {
341 current: None,
342 next: None,
343 right_branches: vec![],
344 };
345 iter.iterate_expr(expr.clone());
346 iter
347 }
348
349 fn iterate_expr(&mut self, expr: Expr) {
350 self.current = Some(expr.clone());
351 match expr {
352 Expr::Seq(lhs, rhs) => {
353 self.right_branches.push(*rhs);
354 self.next = Some(*lhs);
355 }
356 Expr::Choice(lhs, rhs) => {
357 self.right_branches.push(*rhs);
358 self.next = Some(*lhs);
359 }
360 Expr::PosPred(expr)
361 | Expr::NegPred(expr)
362 | Expr::Rep(expr)
363 | Expr::RepOnce(expr)
364 | Expr::RepExact(expr, _)
365 | Expr::RepMin(expr, _)
366 | Expr::RepMax(expr, _)
367 | Expr::RepMinMax(expr, ..)
368 | Expr::Opt(expr)
369 | Expr::Push(expr) => {
370 self.next = Some(*expr);
371 }
372 #[cfg(feature = "grammar-extras")]
373 Expr::NodeTag(expr, _) => {
374 self.next = Some(*expr);
375 }
376 _ => {
377 self.next = None;
378 }
379 }
380 }
381}
382
383impl Iterator for ExprTopDownIterator {
384 type Item = Expr;
385
386 fn next(&mut self) -> Option<Self::Item> {
387 let result = self.current.take();
388
389 if let Some(expr) = self.next.take() {
390 self.iterate_expr(expr);
391 } else if let Some(expr) = self.right_branches.pop() {
392 self.iterate_expr(expr);
393 }
394
395 result
396 }
397}
398
399#[cfg(test)]
400mod tests {
401 use super::*;
402
403 #[test]
404 fn top_down_iterator() {
405 let expr = Expr::Choice(
406 Box::new(Expr::Str(String::from("a"))),
407 Box::new(Expr::Str(String::from("b"))),
408 );
409 let mut top_down = expr.iter_top_down();
410 assert_eq!(top_down.next(), Some(expr));
411 assert_eq!(top_down.next(), Some(Expr::Str(String::from("a"))));
412 assert_eq!(top_down.next(), Some(Expr::Str(String::from("b"))));
413 assert_eq!(top_down.next(), None);
414 }
415
416 #[test]
417 fn identity() {
418 let expr = Expr::Choice(
419 Box::new(Expr::Seq(
420 Box::new(Expr::Ident("a".to_owned())),
421 Box::new(Expr::Str("b".to_owned())),
422 )),
423 Box::new(Expr::PosPred(Box::new(Expr::NegPred(Box::new(Expr::Rep(
424 Box::new(Expr::RepOnce(Box::new(Expr::Opt(Box::new(Expr::Choice(
425 Box::new(Expr::Insens("c".to_owned())),
426 Box::new(Expr::Push(Box::new(Expr::Range(
427 "'d'".to_owned(),
428 "'e'".to_owned(),
429 )))),
430 )))))),
431 )))))),
432 );
433
434 assert_eq!(
435 expr.clone()
436 .map_bottom_up(|expr| expr)
437 .map_top_down(|expr| expr),
438 expr,
439 );
440 }
441
442 mod display {
443 use super::super::*;
444
445 #[test]
446 fn string() {
447 assert_eq!(Expr::Str("a".to_owned()).to_string(), r#""a""#);
448 }
449
450 #[test]
451 fn insens() {
452 assert_eq!(Expr::Insens("a".to_owned()).to_string(), r#"^"a""#);
453 }
454
455 #[test]
456 fn range() {
457 assert_eq!(
458 Expr::Range("a".to_owned(), "z".to_owned()).to_string(),
459 r#"('a'..'z')"#,
460 );
461 }
462
463 #[test]
464 fn ident() {
465 assert_eq!(Expr::Ident("a".to_owned()).to_string(), "a");
466 }
467
468 #[test]
469 fn peek_slice() {
470 assert_eq!(Expr::PeekSlice(0, None).to_string(), "PEEK[0..]");
471 assert_eq!(Expr::PeekSlice(0, Some(-1)).to_string(), "PEEK[0..-1]");
472 }
473
474 #[test]
475 fn pos_pred() {
476 assert_eq!(
477 Expr::PosPred(Box::new(Expr::Ident("e".to_owned()))).to_string(),
478 "&e",
479 );
480 }
481
482 #[test]
483 fn neg_pred() {
484 assert_eq!(
485 Expr::NegPred(Box::new(Expr::Ident("e".to_owned()))).to_string(),
486 "!e",
487 );
488 }
489
490 #[test]
491 fn seq() {
492 assert_eq!(
493 Expr::Seq(
494 Box::new(Expr::Ident("e1".to_owned())),
495 Box::new(Expr::Ident("e2".to_owned())),
496 )
497 .to_string(),
498 "(e1 ~ e2)",
499 );
500 assert_eq!(
501 Expr::Seq(
502 Box::new(Expr::Ident("e1".to_owned())),
503 Box::new(Expr::Seq(
504 Box::new(Expr::Ident("e2".to_owned())),
505 Box::new(Expr::Ident("e3".to_owned())),
506 )),
507 )
508 .to_string(),
509 "(e1 ~ e2 ~ e3)",
510 );
511 assert_eq!(
512 Expr::Seq(
513 Box::new(Expr::Ident("e1".to_owned())),
514 Box::new(Expr::Seq(
515 Box::new(Expr::Ident("e2".to_owned())),
516 Box::new(Expr::Seq(
517 Box::new(Expr::Ident("e3".to_owned())),
518 Box::new(Expr::Ident("e4".to_owned())),
519 )),
520 )),
521 )
522 .to_string(),
523 "(e1 ~ e2 ~ e3 ~ e4)",
524 );
525 assert_eq!(
526 Expr::Seq(
527 Box::new(Expr::Ident("e1".to_owned())),
528 Box::new(Expr::Choice(
529 Box::new(Expr::Ident("e2".to_owned())),
530 Box::new(Expr::Seq(
531 Box::new(Expr::Ident("e3".to_owned())),
532 Box::new(Expr::Ident("e4".to_owned())),
533 )),
534 )),
535 )
536 .to_string(),
537 "(e1 ~ (e2 | (e3 ~ e4)))",
538 );
539 assert_eq!(
540 Expr::Seq(
541 Box::new(Expr::Ident("e1".to_owned())),
542 Box::new(Expr::Seq(
543 Box::new(Expr::Ident("e2".to_owned())),
544 Box::new(Expr::Choice(
545 Box::new(Expr::Ident("e3".to_owned())),
546 Box::new(Expr::Ident("e4".to_owned())),
547 )),
548 )),
549 )
550 .to_string(),
551 "(e1 ~ e2 ~ (e3 | e4))",
552 );
553 }
554
555 #[test]
556 fn choice() {
557 assert_eq!(
558 Expr::Choice(
559 Box::new(Expr::Ident("e1".to_owned())),
560 Box::new(Expr::Ident("e2".to_owned())),
561 )
562 .to_string(),
563 "(e1 | e2)",
564 );
565 assert_eq!(
566 Expr::Choice(
567 Box::new(Expr::Ident("e1".to_owned())),
568 Box::new(Expr::Choice(
569 Box::new(Expr::Ident("e2".to_owned())),
570 Box::new(Expr::Ident("e3".to_owned())),
571 )),
572 )
573 .to_string(),
574 "(e1 | e2 | e3)",
575 );
576 assert_eq!(
577 Expr::Choice(
578 Box::new(Expr::Ident("e1".to_owned())),
579 Box::new(Expr::Choice(
580 Box::new(Expr::Ident("e2".to_owned())),
581 Box::new(Expr::Choice(
582 Box::new(Expr::Ident("e3".to_owned())),
583 Box::new(Expr::Ident("e4".to_owned())),
584 )),
585 )),
586 )
587 .to_string(),
588 "(e1 | e2 | e3 | e4)",
589 );
590 assert_eq!(
591 Expr::Choice(
592 Box::new(Expr::Ident("e1".to_owned())),
593 Box::new(Expr::Seq(
594 Box::new(Expr::Ident("e2".to_owned())),
595 Box::new(Expr::Choice(
596 Box::new(Expr::Ident("e3".to_owned())),
597 Box::new(Expr::Ident("e4".to_owned())),
598 )),
599 )),
600 )
601 .to_string(),
602 "(e1 | (e2 ~ (e3 | e4)))",
603 );
604 }
605
606 #[test]
607 fn opt() {
608 assert_eq!(
609 Expr::Opt(Box::new(Expr::Ident("e".to_owned()))).to_string(),
610 "e?",
611 );
612 }
613
614 #[test]
615 fn rep() {
616 assert_eq!(
617 Expr::Rep(Box::new(Expr::Ident("e".to_owned()))).to_string(),
618 "e*",
619 );
620 }
621
622 #[test]
623 fn rep_once() {
624 assert_eq!(
625 Expr::RepOnce(Box::new(Expr::Ident("e".to_owned()))).to_string(),
626 "e+",
627 );
628 }
629
630 #[test]
631 fn rep_exact() {
632 assert_eq!(
633 Expr::RepExact(Box::new(Expr::Ident("e".to_owned())), 1).to_string(),
634 "e{1}",
635 );
636 }
637
638 #[test]
639 fn rep_min() {
640 assert_eq!(
641 Expr::RepMin(Box::new(Expr::Ident("e".to_owned())), 1).to_string(),
642 "e{1,}",
643 );
644 }
645
646 #[test]
647 fn rep_max() {
648 assert_eq!(
649 Expr::RepMax(Box::new(Expr::Ident("e".to_owned())), 1).to_string(),
650 "e{,1}",
651 );
652 }
653
654 #[test]
655 fn rep_min_max() {
656 assert_eq!(
657 Expr::RepMinMax(Box::new(Expr::Ident("e".to_owned())), 1, 2).to_string(),
658 "e{1, 2}",
659 );
660 }
661
662 #[test]
663 fn skip() {
664 assert_eq!(
665 Expr::Skip(
666 ["a", "bc"]
667 .into_iter()
668 .map(|s| s.to_owned())
669 .collect::<Vec<_>>(),
670 )
671 .to_string(),
672 r#"(!("a" | "bc") ~ ANY)*"#,
673 );
674 }
675
676 #[test]
677 fn push() {
678 assert_eq!(
679 Expr::Push(Box::new(Expr::Ident("e".to_owned()))).to_string(),
680 "PUSH(e)",
681 );
682 }
683
684 #[test]
685 #[cfg(feature = "grammar-extras")]
686 fn node_tag() {
687 assert_eq!(
688 Expr::NodeTag(Box::new(Expr::Ident("expr".to_owned())), "label".to_owned())
689 .to_string(),
690 "(#label = expr)",
691 );
692 }
693 }
694}