1use std::char;
13use std::iter::Peekable;
14
15use pest::error::{Error, ErrorVariant};
16use pest::iterators::{Pair, Pairs};
17use pest::pratt_parser::{Assoc, Op, PrattParser};
18use pest::{Parser, Position, Span};
19
20use crate::ast::{Expr, Rule as AstRule, RuleType};
21use crate::validator;
22
23#[allow(missing_docs, unused_qualifications)]
24mod grammar {
25 #[cfg(not(feature = "not-bootstrap-in-src"))]
26 include!("grammar.rs");
27
28 #[cfg(feature = "not-bootstrap-in-src")]
29 include!(concat!(env!("OUT_DIR"), "/__pest_grammar.rs"));
30}
31
32pub use self::grammar::*;
33
34#[allow(clippy::perf)]
36pub fn parse(rule: Rule, data: &str) -> Result<Pairs<'_, Rule>, Error<Rule>> {
37 PestParser::parse(rule, data)
38}
39
40#[derive(Clone, Debug, Eq, PartialEq)]
42pub struct ParserRule<'i> {
43 pub name: String,
45 pub span: Span<'i>,
47 pub ty: RuleType,
49 pub node: ParserNode<'i>,
51}
52
53#[derive(Clone, Debug, Eq, PartialEq)]
55pub struct ParserNode<'i> {
56 pub expr: ParserExpr<'i>,
58 pub span: Span<'i>,
60}
61
62impl<'i> ParserNode<'i> {
63 pub fn filter_map_top_down<F, T>(self, mut f: F) -> Vec<T>
65 where
66 F: FnMut(ParserNode<'i>) -> Option<T>,
67 {
68 pub fn filter_internal<'i, F, T>(node: ParserNode<'i>, f: &mut F, result: &mut Vec<T>)
69 where
70 F: FnMut(ParserNode<'i>) -> Option<T>,
71 {
72 if let Some(value) = f(node.clone()) {
73 result.push(value);
74 }
75
76 match node.expr {
77 ParserExpr::PosPred(node) => {
78 filter_internal(*node, f, result);
79 }
80 ParserExpr::NegPred(node) => {
81 filter_internal(*node, f, result);
82 }
83 ParserExpr::Seq(lhs, rhs) => {
84 filter_internal(*lhs, f, result);
85 filter_internal(*rhs, f, result);
86 }
87 ParserExpr::Choice(lhs, rhs) => {
88 filter_internal(*lhs, f, result);
89 filter_internal(*rhs, f, result);
90 }
91 ParserExpr::Rep(node) => {
92 filter_internal(*node, f, result);
93 }
94 ParserExpr::RepOnce(node) => {
95 filter_internal(*node, f, result);
96 }
97 ParserExpr::RepExact(node, _) => {
98 filter_internal(*node, f, result);
99 }
100 ParserExpr::RepMin(node, _) => {
101 filter_internal(*node, f, result);
102 }
103 ParserExpr::RepMax(node, _) => {
104 filter_internal(*node, f, result);
105 }
106 ParserExpr::RepMinMax(node, ..) => {
107 filter_internal(*node, f, result);
108 }
109 ParserExpr::Opt(node) => {
110 filter_internal(*node, f, result);
111 }
112 ParserExpr::Push(node) => {
113 filter_internal(*node, f, result);
114 }
115 _ => (),
116 }
117 }
118
119 let mut result = vec![];
120
121 filter_internal(self, &mut f, &mut result);
122
123 result
124 }
125}
126
127#[derive(Clone, Debug, Eq, PartialEq)]
129pub enum ParserExpr<'i> {
130 Str(String),
132 Insens(String),
134 Range(String, String),
136 Ident(String),
138 PeekSlice(i32, Option<i32>),
140 PosPred(Box<ParserNode<'i>>),
142 NegPred(Box<ParserNode<'i>>),
144 Seq(Box<ParserNode<'i>>, Box<ParserNode<'i>>),
146 Choice(Box<ParserNode<'i>>, Box<ParserNode<'i>>),
148 Opt(Box<ParserNode<'i>>),
150 Rep(Box<ParserNode<'i>>),
152 RepOnce(Box<ParserNode<'i>>),
154 RepExact(Box<ParserNode<'i>>, u32),
156 RepMin(Box<ParserNode<'i>>, u32),
158 RepMax(Box<ParserNode<'i>>, u32),
160 RepMinMax(Box<ParserNode<'i>>, u32, u32),
162 Push(Box<ParserNode<'i>>),
164 #[cfg(feature = "grammar-extras")]
166 NodeTag(Box<ParserNode<'i>>, String),
167}
168
169fn convert_rule(rule: ParserRule<'_>) -> AstRule {
170 let ParserRule { name, ty, node, .. } = rule;
171 let expr = convert_node(node);
172 AstRule { name, ty, expr }
173}
174
175fn convert_node(node: ParserNode<'_>) -> Expr {
176 match node.expr {
177 ParserExpr::Str(string) => Expr::Str(string),
178 ParserExpr::Insens(string) => Expr::Insens(string),
179 ParserExpr::Range(start, end) => Expr::Range(start, end),
180 ParserExpr::Ident(ident) => Expr::Ident(ident),
181 ParserExpr::PeekSlice(start, end) => Expr::PeekSlice(start, end),
182 ParserExpr::PosPred(node) => Expr::PosPred(Box::new(convert_node(*node))),
183 ParserExpr::NegPred(node) => Expr::NegPred(Box::new(convert_node(*node))),
184 ParserExpr::Seq(node1, node2) => Expr::Seq(
185 Box::new(convert_node(*node1)),
186 Box::new(convert_node(*node2)),
187 ),
188 ParserExpr::Choice(node1, node2) => Expr::Choice(
189 Box::new(convert_node(*node1)),
190 Box::new(convert_node(*node2)),
191 ),
192 ParserExpr::Opt(node) => Expr::Opt(Box::new(convert_node(*node))),
193 ParserExpr::Rep(node) => Expr::Rep(Box::new(convert_node(*node))),
194 ParserExpr::RepOnce(node) => Expr::RepOnce(Box::new(convert_node(*node))),
195 ParserExpr::RepExact(node, num) => Expr::RepExact(Box::new(convert_node(*node)), num),
196 ParserExpr::RepMin(node, max) => Expr::RepMin(Box::new(convert_node(*node)), max),
197 ParserExpr::RepMax(node, max) => Expr::RepMax(Box::new(convert_node(*node)), max),
198 ParserExpr::RepMinMax(node, min, max) => {
199 Expr::RepMinMax(Box::new(convert_node(*node)), min, max)
200 }
201 ParserExpr::Push(node) => Expr::Push(Box::new(convert_node(*node))),
202 #[cfg(feature = "grammar-extras")]
203 ParserExpr::NodeTag(node, tag) => Expr::NodeTag(Box::new(convert_node(*node)), tag),
204 }
205}
206
207pub fn consume_rules(pairs: Pairs<'_, Rule>) -> Result<Vec<AstRule>, Vec<Error<Rule>>> {
209 let rules = consume_rules_with_spans(pairs)?;
210 let errors = validator::validate_ast(&rules);
211 if errors.is_empty() {
212 Ok(rules.into_iter().map(convert_rule).collect())
213 } else {
214 Err(errors)
215 }
216}
217
218#[inline]
221pub fn rename_meta_rule(rule: &Rule) -> String {
222 match *rule {
223 Rule::grammar_rule => "rule".to_owned(),
224 Rule::_push => "PUSH".to_owned(),
225 Rule::assignment_operator => "`=`".to_owned(),
226 Rule::silent_modifier => "`_`".to_owned(),
227 Rule::atomic_modifier => "`@`".to_owned(),
228 Rule::compound_atomic_modifier => "`$`".to_owned(),
229 Rule::non_atomic_modifier => "`!`".to_owned(),
230 Rule::opening_brace => "`{`".to_owned(),
231 Rule::closing_brace => "`}`".to_owned(),
232 Rule::opening_brack => "`[`".to_owned(),
233 Rule::closing_brack => "`]`".to_owned(),
234 Rule::opening_paren => "`(`".to_owned(),
235 Rule::positive_predicate_operator => "`&`".to_owned(),
236 Rule::negative_predicate_operator => "`!`".to_owned(),
237 Rule::sequence_operator => "`&`".to_owned(),
238 Rule::choice_operator => "`|`".to_owned(),
239 Rule::optional_operator => "`?`".to_owned(),
240 Rule::repeat_operator => "`*`".to_owned(),
241 Rule::repeat_once_operator => "`+`".to_owned(),
242 Rule::comma => "`,`".to_owned(),
243 Rule::closing_paren => "`)`".to_owned(),
244 Rule::quote => "`\"`".to_owned(),
245 Rule::insensitive_string => "`^`".to_owned(),
246 Rule::range_operator => "`..`".to_owned(),
247 Rule::single_quote => "`'`".to_owned(),
248 Rule::grammar_doc => "//!".to_owned(),
249 Rule::line_doc => "///".to_owned(),
250 other_rule => format!("{:?}", other_rule),
251 }
252}
253
254fn consume_rules_with_spans(
255 pairs: Pairs<'_, Rule>,
256) -> Result<Vec<ParserRule<'_>>, Vec<Error<Rule>>> {
257 let pratt = PrattParser::new()
258 .op(Op::infix(Rule::choice_operator, Assoc::Left))
259 .op(Op::infix(Rule::sequence_operator, Assoc::Left));
260
261 pairs
262 .filter(|pair| pair.as_rule() == Rule::grammar_rule)
263 .filter(|pair| {
264 let mut pairs = pair.clone().into_inner();
266 let pair = pairs.next().unwrap();
267
268 pair.as_rule() != Rule::line_doc
269 })
270 .map(|pair| {
271 let mut pairs = pair.into_inner().peekable();
272
273 let span = pairs.next().unwrap().as_span();
274 let name = span.as_str().to_owned();
275
276 pairs.next().unwrap(); let ty = if pairs.peek().unwrap().as_rule() != Rule::opening_brace {
279 match pairs.next().unwrap().as_rule() {
280 Rule::silent_modifier => RuleType::Silent,
281 Rule::atomic_modifier => RuleType::Atomic,
282 Rule::compound_atomic_modifier => RuleType::CompoundAtomic,
283 Rule::non_atomic_modifier => RuleType::NonAtomic,
284 _ => unreachable!(),
285 }
286 } else {
287 RuleType::Normal
288 };
289
290 pairs.next().unwrap(); let mut inner_nodes = pairs.next().unwrap().into_inner().peekable();
294 if inner_nodes.peek().unwrap().as_rule() == Rule::choice_operator {
295 inner_nodes.next().unwrap();
296 }
297
298 let node = consume_expr(inner_nodes, &pratt)?;
299
300 Ok(ParserRule {
301 name,
302 span,
303 ty,
304 node,
305 })
306 })
307 .collect()
308}
309
310fn get_node_tag<'i>(
311 pairs: &mut Peekable<Pairs<'i, Rule>>,
312) -> (Pair<'i, Rule>, Option<(String, Position<'i>)>) {
313 let pair_or_tag = pairs.next().unwrap();
314 if let Some(next_pair) = pairs.peek() {
315 if next_pair.as_rule() == Rule::assignment_operator {
316 pairs.next().unwrap();
317 let pair = pairs.next().unwrap();
318 (
319 pair,
320 Some((
321 pair_or_tag.as_str()[1..].to_string(),
322 pair_or_tag.as_span().start_pos(),
323 )),
324 )
325 } else {
326 (pair_or_tag, None)
327 }
328 } else {
329 (pair_or_tag, None)
330 }
331}
332
333fn consume_expr<'i>(
334 pairs: Peekable<Pairs<'i, Rule>>,
335 pratt: &PrattParser<Rule>,
336) -> Result<ParserNode<'i>, Vec<Error<Rule>>> {
337 fn unaries<'i>(
338 mut pairs: Peekable<Pairs<'i, Rule>>,
339 pratt: &PrattParser<Rule>,
340 ) -> Result<ParserNode<'i>, Vec<Error<Rule>>> {
341 #[cfg(feature = "grammar-extras")]
342 let (pair, tag_start) = get_node_tag(&mut pairs);
343 #[cfg(not(feature = "grammar-extras"))]
344 let (pair, _tag_start) = get_node_tag(&mut pairs);
345
346 let node = match pair.as_rule() {
347 Rule::opening_paren => {
348 let node = unaries(pairs, pratt)?;
349 let end = node.span.end_pos();
350
351 ParserNode {
352 expr: node.expr,
353 span: pair.as_span().start_pos().span(&end),
354 }
355 }
356 Rule::positive_predicate_operator => {
357 let node = unaries(pairs, pratt)?;
358 let end = node.span.end_pos();
359
360 ParserNode {
361 expr: ParserExpr::PosPred(Box::new(node)),
362 span: pair.as_span().start_pos().span(&end),
363 }
364 }
365 Rule::negative_predicate_operator => {
366 let node = unaries(pairs, pratt)?;
367 let end = node.span.end_pos();
368
369 ParserNode {
370 expr: ParserExpr::NegPred(Box::new(node)),
371 span: pair.as_span().start_pos().span(&end),
372 }
373 }
374 other_rule => {
375 let node = match other_rule {
376 Rule::expression => consume_expr(pair.into_inner().peekable(), pratt)?,
377 Rule::_push => {
378 let start = pair.clone().as_span().start_pos();
379 let mut pairs = pair.into_inner();
380 pairs.next().unwrap(); let pair = pairs.next().unwrap();
382
383 let node = consume_expr(pair.into_inner().peekable(), pratt)?;
384 let end = node.span.end_pos();
385
386 ParserNode {
387 expr: ParserExpr::Push(Box::new(node)),
388 span: start.span(&end),
389 }
390 }
391 Rule::peek_slice => {
392 let mut pairs = pair.clone().into_inner();
393 pairs.next().unwrap(); let pair_start = pairs.next().unwrap(); let start: i32 = match pair_start.as_rule() {
396 Rule::range_operator => 0,
397 Rule::integer => {
398 pairs.next().unwrap(); pair_start.as_str().parse().unwrap()
400 }
401 _ => unreachable!("peek start"),
402 };
403 let pair_end = pairs.next().unwrap(); let end: Option<i32> = match pair_end.as_rule() {
405 Rule::closing_brack => None,
406 Rule::integer => {
407 pairs.next().unwrap(); Some(pair_end.as_str().parse().unwrap())
409 }
410 _ => unreachable!("peek end"),
411 };
412 ParserNode {
413 expr: ParserExpr::PeekSlice(start, end),
414 span: pair.as_span(),
415 }
416 }
417 Rule::identifier => ParserNode {
418 expr: ParserExpr::Ident(pair.as_str().to_owned()),
419 span: pair.clone().as_span(),
420 },
421 Rule::string => {
422 let string = unescape(pair.as_str()).expect("incorrect string literal");
423 ParserNode {
424 expr: ParserExpr::Str(string[1..string.len() - 1].to_owned()),
425 span: pair.clone().as_span(),
426 }
427 }
428 Rule::insensitive_string => {
429 let string = unescape(pair.as_str()).expect("incorrect string literal");
430 ParserNode {
431 expr: ParserExpr::Insens(string[2..string.len() - 1].to_owned()),
432 span: pair.clone().as_span(),
433 }
434 }
435 Rule::range => {
436 let mut pairs = pair.into_inner();
437 let pair = pairs.next().unwrap();
438 let start = unescape(pair.as_str()).expect("incorrect char literal");
439 let start_pos = pair.clone().as_span().start_pos();
440 pairs.next();
441 let pair = pairs.next().unwrap();
442 let end = unescape(pair.as_str()).expect("incorrect char literal");
443 let end_pos = pair.clone().as_span().end_pos();
444
445 ParserNode {
446 expr: ParserExpr::Range(
447 start[1..start.len() - 1].to_owned(),
448 end[1..end.len() - 1].to_owned(),
449 ),
450 span: start_pos.span(&end_pos),
451 }
452 }
453 x => unreachable!("other rule: {:?}", x),
454 };
455
456 pairs.try_fold(node, |node: ParserNode<'i>, pair: Pair<'i, Rule>| {
457 let node = match pair.as_rule() {
458 Rule::optional_operator => {
459 let start = node.span.start_pos();
460 ParserNode {
461 expr: ParserExpr::Opt(Box::new(node)),
462 span: start.span(&pair.as_span().end_pos()),
463 }
464 }
465 Rule::repeat_operator => {
466 let start = node.span.start_pos();
467 ParserNode {
468 expr: ParserExpr::Rep(Box::new(node)),
469 span: start.span(&pair.as_span().end_pos()),
470 }
471 }
472 Rule::repeat_once_operator => {
473 let start = node.span.start_pos();
474 ParserNode {
475 expr: ParserExpr::RepOnce(Box::new(node)),
476 span: start.span(&pair.as_span().end_pos()),
477 }
478 }
479 Rule::repeat_exact => {
480 let mut inner = pair.clone().into_inner();
481
482 inner.next().unwrap(); let number = inner.next().unwrap();
485 let num = if let Ok(num) = number.as_str().parse::<u32>() {
486 num
487 } else {
488 return Err(vec![Error::new_from_span(
489 ErrorVariant::CustomError {
490 message: "number cannot overflow u32".to_owned(),
491 },
492 number.as_span(),
493 )]);
494 };
495
496 if num == 0 {
497 let error: Error<Rule> = Error::new_from_span(
498 ErrorVariant::CustomError {
499 message: "cannot repeat 0 times".to_owned(),
500 },
501 number.as_span(),
502 );
503
504 return Err(vec![error]);
505 }
506
507 let start = node.span.start_pos();
508 ParserNode {
509 expr: ParserExpr::RepExact(Box::new(node), num),
510 span: start.span(&pair.as_span().end_pos()),
511 }
512 }
513 Rule::repeat_min => {
514 let mut inner = pair.clone().into_inner();
515
516 inner.next().unwrap(); let min_number = inner.next().unwrap();
519 let min = if let Ok(min) = min_number.as_str().parse::<u32>() {
520 min
521 } else {
522 return Err(vec![Error::new_from_span(
523 ErrorVariant::CustomError {
524 message: "number cannot overflow u32".to_owned(),
525 },
526 min_number.as_span(),
527 )]);
528 };
529
530 let start = node.span.start_pos();
531 ParserNode {
532 expr: ParserExpr::RepMin(Box::new(node), min),
533 span: start.span(&pair.as_span().end_pos()),
534 }
535 }
536 Rule::repeat_max => {
537 let mut inner = pair.clone().into_inner();
538
539 inner.next().unwrap(); inner.next().unwrap(); let max_number = inner.next().unwrap();
543 let max = if let Ok(max) = max_number.as_str().parse::<u32>() {
544 max
545 } else {
546 return Err(vec![Error::new_from_span(
547 ErrorVariant::CustomError {
548 message: "number cannot overflow u32".to_owned(),
549 },
550 max_number.as_span(),
551 )]);
552 };
553
554 if max == 0 {
555 let error: Error<Rule> = Error::new_from_span(
556 ErrorVariant::CustomError {
557 message: "cannot repeat 0 times".to_owned(),
558 },
559 max_number.as_span(),
560 );
561
562 return Err(vec![error]);
563 }
564
565 let start = node.span.start_pos();
566 ParserNode {
567 expr: ParserExpr::RepMax(Box::new(node), max),
568 span: start.span(&pair.as_span().end_pos()),
569 }
570 }
571 Rule::repeat_min_max => {
572 let mut inner = pair.clone().into_inner();
573
574 inner.next().unwrap(); let min_number = inner.next().unwrap();
577 let min = if let Ok(min) = min_number.as_str().parse::<u32>() {
578 min
579 } else {
580 return Err(vec![Error::new_from_span(
581 ErrorVariant::CustomError {
582 message: "number cannot overflow u32".to_owned(),
583 },
584 min_number.as_span(),
585 )]);
586 };
587
588 inner.next().unwrap(); let max_number = inner.next().unwrap();
591 let max = if let Ok(max) = max_number.as_str().parse::<u32>() {
592 max
593 } else {
594 return Err(vec![Error::new_from_span(
595 ErrorVariant::CustomError {
596 message: "number cannot overflow u32".to_owned(),
597 },
598 max_number.as_span(),
599 )]);
600 };
601
602 if max == 0 {
603 let error: Error<Rule> = Error::new_from_span(
604 ErrorVariant::CustomError {
605 message: "cannot repeat 0 times".to_owned(),
606 },
607 max_number.as_span(),
608 );
609
610 return Err(vec![error]);
611 }
612
613 let start = node.span.start_pos();
614 ParserNode {
615 expr: ParserExpr::RepMinMax(Box::new(node), min, max),
616 span: start.span(&pair.as_span().end_pos()),
617 }
618 }
619 Rule::closing_paren => {
620 let start = node.span.start_pos();
621
622 ParserNode {
623 expr: node.expr,
624 span: start.span(&pair.as_span().end_pos()),
625 }
626 }
627 rule => unreachable!("node: {:?}", rule),
628 };
629
630 Ok(node)
631 })?
632 }
633 };
634 #[cfg(feature = "grammar-extras")]
635 if let Some((tag, start)) = tag_start {
636 let span = start.span(&node.span.end_pos());
637 Ok(ParserNode {
638 expr: ParserExpr::NodeTag(Box::new(node), tag),
639 span,
640 })
641 } else {
642 Ok(node)
643 }
644 #[cfg(not(feature = "grammar-extras"))]
645 Ok(node)
646 }
647
648 let term = |pair: Pair<'i, Rule>| unaries(pair.into_inner().peekable(), pratt);
649 let infix = |lhs: Result<ParserNode<'i>, Vec<Error<Rule>>>,
650 op: Pair<'i, Rule>,
651 rhs: Result<ParserNode<'i>, Vec<Error<Rule>>>| match op.as_rule() {
652 Rule::sequence_operator => {
653 let lhs = lhs?;
654 let rhs = rhs?;
655
656 let start = lhs.span.start_pos();
657 let end = rhs.span.end_pos();
658
659 Ok(ParserNode {
660 expr: ParserExpr::Seq(Box::new(lhs), Box::new(rhs)),
661 span: start.span(&end),
662 })
663 }
664 Rule::choice_operator => {
665 let lhs = lhs?;
666 let rhs = rhs?;
667
668 let start = lhs.span.start_pos();
669 let end = rhs.span.end_pos();
670
671 Ok(ParserNode {
672 expr: ParserExpr::Choice(Box::new(lhs), Box::new(rhs)),
673 span: start.span(&end),
674 })
675 }
676 _ => unreachable!("infix"),
677 };
678
679 pratt.map_primary(term).map_infix(infix).parse(pairs)
680}
681
682fn unescape(string: &str) -> Option<String> {
683 let mut result = String::new();
684 let mut chars = string.chars();
685
686 loop {
687 match chars.next() {
688 Some('\\') => match chars.next()? {
689 '"' => result.push('"'),
690 '\\' => result.push('\\'),
691 'r' => result.push('\r'),
692 'n' => result.push('\n'),
693 't' => result.push('\t'),
694 '0' => result.push('\0'),
695 '\'' => result.push('\''),
696 'x' => {
697 let string: String = chars.clone().take(2).collect();
698
699 if string.len() != 2 {
700 return None;
701 }
702
703 for _ in 0..string.len() {
704 chars.next()?;
705 }
706
707 let value = u8::from_str_radix(&string, 16).ok()?;
708
709 result.push(char::from(value));
710 }
711 'u' => {
712 if chars.next()? != '{' {
713 return None;
714 }
715
716 let string: String = chars.clone().take_while(|c| *c != '}').collect();
717
718 if string.len() < 2 || 6 < string.len() {
719 return None;
720 }
721
722 for _ in 0..string.len() + 1 {
723 chars.next()?;
724 }
725
726 let value = u32::from_str_radix(&string, 16).ok()?;
727
728 result.push(char::from_u32(value)?);
729 }
730 _ => return None,
731 },
732 Some(c) => result.push(c),
733 None => return Some(result),
734 };
735 }
736}
737
738#[cfg(test)]
739mod tests {
740 use std::convert::TryInto;
741
742 use super::super::unwrap_or_report;
743 use super::*;
744
745 #[test]
746 fn rules() {
747 parses_to! {
748 parser: PestParser,
749 input: "a = { b } c = { d }",
750 rule: Rule::grammar_rules,
751 tokens: [
752 grammar_rule(0, 9, [
753 identifier(0, 1),
754 assignment_operator(2, 3),
755 opening_brace(4, 5),
756 expression(6, 8, [
757 term(6, 8, [
758 identifier(6, 7)
759 ])
760 ]),
761 closing_brace(8, 9)
762 ]),
763 grammar_rule(10, 19, [
764 identifier(10, 11),
765 assignment_operator(12, 13),
766 opening_brace(14, 15),
767 expression(16, 18, [
768 term(16, 18, [
769 identifier(16, 17)
770 ])
771 ]),
772 closing_brace(18, 19)
773 ])
774 ]
775 };
776 }
777
778 #[test]
779 fn rule() {
780 parses_to! {
781 parser: PestParser,
782 input: "a = ! { b ~ c }",
783 rule: Rule::grammar_rule,
784 tokens: [
785 grammar_rule(0, 15, [
786 identifier(0, 1),
787 assignment_operator(2, 3),
788 non_atomic_modifier(4, 5),
789 opening_brace(6, 7),
790 expression(8, 14, [
791 term(8, 10, [
792 identifier(8, 9)
793 ]),
794 sequence_operator(10, 11),
795 term(12, 14, [
796 identifier(12, 13)
797 ])
798 ]),
799 closing_brace(14, 15)
800 ])
801 ]
802 };
803 }
804
805 #[test]
806 fn expression() {
807 parses_to! {
808 parser: PestParser,
809 input: "_a | 'a'..'b' ~ !^\"abc\" ~ (d | e)*?",
810 rule: Rule::expression,
811 tokens: [
812 expression(0, 35, [
813 term(0, 3, [
814 identifier(0, 2)
815 ]),
816 choice_operator(3, 4),
817 term(5, 14, [
818 range(5, 13, [
819 character(5, 8, [
820 single_quote(5, 6),
821 inner_chr(6, 7),
822 single_quote(7, 8)
823 ]),
824 range_operator(8, 10),
825 character(10, 13, [
826 single_quote(10, 11),
827 inner_chr(11, 12),
828 single_quote(12, 13)
829 ])
830 ])
831 ]),
832 sequence_operator(14, 15),
833 term(16, 24, [
834 negative_predicate_operator(16, 17),
835 insensitive_string(17, 23, [
836 string(18, 23, [
837 quote(18, 19),
838 inner_str(19, 22),
839 quote(22, 23)
840 ])
841 ])
842 ]),
843 sequence_operator(24, 25),
844 term(26, 35, [
845 opening_paren(26, 27),
846 expression(27, 32, [
847 term(27, 29, [
848 identifier(27, 28)
849 ]),
850 choice_operator(29, 30),
851 term(31, 32, [
852 identifier(31, 32)
853 ])
854 ]),
855 closing_paren(32, 33),
856 repeat_operator(33, 34),
857 optional_operator(34, 35)
858 ])
859 ])
860 ]
861 };
862 }
863
864 #[test]
865 fn repeat_exact() {
866 parses_to! {
867 parser: PestParser,
868 input: "{1}",
869 rule: Rule::repeat_exact,
870 tokens: [
871 repeat_exact(0, 3, [
872 opening_brace(0, 1),
873 number(1, 2),
874 closing_brace(2, 3)
875 ])
876 ]
877 };
878 }
879
880 #[test]
881 fn repeat_min() {
882 parses_to! {
883 parser: PestParser,
884 input: "{2,}",
885 rule: Rule::repeat_min,
886 tokens: [
887 repeat_min(0, 4, [
888 opening_brace(0,1),
889 number(1,2),
890 comma(2,3),
891 closing_brace(3,4)
892 ])
893 ]
894 }
895 }
896
897 #[test]
898 fn repeat_max() {
899 parses_to! {
900 parser: PestParser,
901 input: "{, 3}",
902 rule: Rule::repeat_max,
903 tokens: [
904 repeat_max(0, 5, [
905 opening_brace(0,1),
906 comma(1,2),
907 number(3,4),
908 closing_brace(4,5)
909 ])
910 ]
911 }
912 }
913
914 #[test]
915 fn repeat_min_max() {
916 parses_to! {
917 parser: PestParser,
918 input: "{1, 2}",
919 rule: Rule::repeat_min_max,
920 tokens: [
921 repeat_min_max(0, 6, [
922 opening_brace(0, 1),
923 number(1, 2),
924 comma(2, 3),
925 number(4, 5),
926 closing_brace(5, 6)
927 ])
928 ]
929 };
930 }
931
932 #[test]
933 fn push() {
934 parses_to! {
935 parser: PestParser,
936 input: "PUSH ( a )",
937 rule: Rule::_push,
938 tokens: [
939 _push(0, 10, [
940 opening_paren(5, 6),
941 expression(7, 9, [
942 term(7, 9, [
943 identifier(7, 8)
944 ])
945 ]),
946 closing_paren(9, 10)
947 ])
948 ]
949 };
950 }
951
952 #[test]
953 fn peek_slice_all() {
954 parses_to! {
955 parser: PestParser,
956 input: "PEEK[..]",
957 rule: Rule::peek_slice,
958 tokens: [
959 peek_slice(0, 8, [
960 opening_brack(4, 5),
961 range_operator(5, 7),
962 closing_brack(7, 8)
963 ])
964 ]
965 };
966 }
967
968 #[test]
969 fn peek_slice_start() {
970 parses_to! {
971 parser: PestParser,
972 input: "PEEK[1..]",
973 rule: Rule::peek_slice,
974 tokens: [
975 peek_slice(0, 9, [
976 opening_brack(4, 5),
977 integer(5, 6),
978 range_operator(6, 8),
979 closing_brack(8, 9)
980 ])
981 ]
982 };
983 }
984
985 #[test]
986 fn peek_slice_end() {
987 parses_to! {
988 parser: PestParser,
989 input: "PEEK[ ..-1]",
990 rule: Rule::peek_slice,
991 tokens: [
992 peek_slice(0, 11, [
993 opening_brack(4, 5),
994 range_operator(6, 8),
995 integer(8, 10),
996 closing_brack(10, 11)
997 ])
998 ]
999 };
1000 }
1001
1002 #[test]
1003 fn peek_slice_start_end() {
1004 parses_to! {
1005 parser: PestParser,
1006 input: "PEEK[-5..10]",
1007 rule: Rule::peek_slice,
1008 tokens: [
1009 peek_slice(0, 12, [
1010 opening_brack(4, 5),
1011 integer(5, 7),
1012 range_operator(7, 9),
1013 integer(9, 11),
1014 closing_brack(11, 12)
1015 ])
1016 ]
1017 };
1018 }
1019
1020 #[test]
1021 fn identifier() {
1022 parses_to! {
1023 parser: PestParser,
1024 input: "_a8943",
1025 rule: Rule::identifier,
1026 tokens: [
1027 identifier(0, 6)
1028 ]
1029 };
1030 }
1031
1032 #[test]
1033 fn string() {
1034 parses_to! {
1035 parser: PestParser,
1036 input: "\"aaaaa\\n\\r\\t\\\\\\0\\'\\\"\\x0F\\u{123abC}\\u{12}aaaaa\"",
1037 rule: Rule::string,
1038 tokens: [
1039 string(0, 46, [
1040 quote(0, 1),
1041 inner_str(1, 45),
1042 quote(45, 46)
1043 ])
1044 ]
1045 };
1046 }
1047
1048 #[test]
1049 fn insensitive_string() {
1050 parses_to! {
1051 parser: PestParser,
1052 input: "^ \"\\\"hi\"",
1053 rule: Rule::insensitive_string,
1054 tokens: [
1055 insensitive_string(0, 9, [
1056 string(3, 9, [
1057 quote(3, 4),
1058 inner_str(4, 8),
1059 quote(8, 9)
1060 ])
1061 ])
1062 ]
1063 };
1064 }
1065
1066 #[test]
1067 fn range() {
1068 parses_to! {
1069 parser: PestParser,
1070 input: "'\\n' .. '\\x1a'",
1071 rule: Rule::range,
1072 tokens: [
1073 range(0, 14, [
1074 character(0, 4, [
1075 single_quote(0, 1),
1076 inner_chr(1, 3),
1077 single_quote(3, 4)
1078 ]),
1079 range_operator(5, 7),
1080 character(8, 14, [
1081 single_quote(8, 9),
1082 inner_chr(9, 13),
1083 single_quote(13, 14)
1084 ])
1085 ])
1086 ]
1087 };
1088 }
1089
1090 #[test]
1091 fn character() {
1092 parses_to! {
1093 parser: PestParser,
1094 input: "'\\u{123abC}'",
1095 rule: Rule::character,
1096 tokens: [
1097 character(0, 12, [
1098 single_quote(0, 1),
1099 inner_chr(1, 11),
1100 single_quote(11, 12)
1101 ])
1102 ]
1103 };
1104 }
1105
1106 #[test]
1107 fn number() {
1108 parses_to! {
1109 parser: PestParser,
1110 input: "0123",
1111 rule: Rule::number,
1112 tokens: [
1113 number(0, 4)
1114 ]
1115 };
1116 }
1117
1118 #[test]
1119 fn comment() {
1120 parses_to! {
1121 parser: PestParser,
1122 input: "a ~ // asda\n b",
1123 rule: Rule::expression,
1124 tokens: [
1125 expression(0, 17, [
1126 term(0, 2, [
1127 identifier(0, 1)
1128 ]),
1129 sequence_operator(2, 3),
1130 term(16, 17, [
1131 identifier(16, 17)
1132 ])
1133 ])
1134 ]
1135 };
1136 }
1137
1138 #[test]
1139 fn grammar_doc_and_line_doc() {
1140 let input = "//! hello\n/// world\na = { \"a\" }";
1141 parses_to! {
1142 parser: PestParser,
1143 input: input,
1144 rule: Rule::grammar_rules,
1145 tokens: [
1146 grammar_doc(0, 9, [
1147 inner_doc(4, 9),
1148 ]),
1149 grammar_rule(10, 19, [
1150 line_doc(10, 19, [
1151 inner_doc(14, 19),
1152 ]),
1153 ]),
1154 grammar_rule(20, 31, [
1155 identifier(20, 21),
1156 assignment_operator(22, 23),
1157 opening_brace(24, 25),
1158 expression(26, 30, [
1159 term(26, 30, [
1160 string(26, 29, [
1161 quote(26, 27),
1162 inner_str(27, 28),
1163 quote(28, 29)
1164 ])
1165 ])
1166 ]),
1167 closing_brace(30, 31),
1168 ])
1169 ]
1170 };
1171 }
1172
1173 #[test]
1174 fn wrong_identifier() {
1175 fails_with! {
1176 parser: PestParser,
1177 input: "0",
1178 rule: Rule::grammar_rules,
1179 positives: vec![Rule::EOI, Rule::grammar_rule, Rule::grammar_doc],
1180 negatives: vec![],
1181 pos: 0
1182 };
1183 }
1184
1185 #[test]
1186 fn missing_assignment_operator() {
1187 fails_with! {
1188 parser: PestParser,
1189 input: "a {}",
1190 rule: Rule::grammar_rules,
1191 positives: vec![Rule::assignment_operator],
1192 negatives: vec![],
1193 pos: 2
1194 };
1195 }
1196
1197 #[test]
1198 fn wrong_modifier() {
1199 fails_with! {
1200 parser: PestParser,
1201 input: "a = *{}",
1202 rule: Rule::grammar_rules,
1203 positives: vec![
1204 Rule::opening_brace,
1205 Rule::silent_modifier,
1206 Rule::atomic_modifier,
1207 Rule::compound_atomic_modifier,
1208 Rule::non_atomic_modifier
1209 ],
1210 negatives: vec![],
1211 pos: 4
1212 };
1213 }
1214
1215 #[test]
1216 fn missing_opening_brace() {
1217 fails_with! {
1218 parser: PestParser,
1219 input: "a = _",
1220 rule: Rule::grammar_rules,
1221 positives: vec![Rule::opening_brace],
1222 negatives: vec![],
1223 pos: 5
1224 };
1225 }
1226
1227 #[test]
1228 fn empty_rule() {
1229 fails_with! {
1230 parser: PestParser,
1231 input: "a = {}",
1232 rule: Rule::grammar_rules,
1233 positives: vec![Rule::expression],
1234 negatives: vec![],
1235 pos: 5
1236 };
1237 }
1238
1239 #[test]
1240 fn missing_rhs() {
1241 fails_with! {
1242 parser: PestParser,
1243 input: "a = { b ~ }",
1244 rule: Rule::grammar_rules,
1245 positives: vec![Rule::term],
1246 negatives: vec![],
1247 pos: 10
1248 };
1249 }
1250
1251 #[test]
1252 fn incorrect_prefix() {
1253 fails_with! {
1254 parser: PestParser,
1255 input: "a = { ~ b}",
1256 rule: Rule::grammar_rules,
1257 positives: vec![Rule::expression],
1258 negatives: vec![],
1259 pos: 6
1260 };
1261 }
1262
1263 #[test]
1264 fn wrong_op() {
1265 fails_with! {
1266 parser: PestParser,
1267 input: "a = { b % }",
1268 rule: Rule::grammar_rules,
1269 positives: vec![
1270 Rule::opening_brace,
1271 Rule::closing_brace,
1272 Rule::sequence_operator,
1273 Rule::choice_operator,
1274 Rule::optional_operator,
1275 Rule::repeat_operator,
1276 Rule::repeat_once_operator
1277 ],
1278 negatives: vec![],
1279 pos: 8
1280 };
1281 }
1282
1283 #[test]
1284 fn missing_closing_paren() {
1285 fails_with! {
1286 parser: PestParser,
1287 input: "a = { (b }",
1288 rule: Rule::grammar_rules,
1289 positives: vec![
1290 Rule::opening_brace,
1291 Rule::closing_paren,
1292 Rule::sequence_operator,
1293 Rule::choice_operator,
1294 Rule::optional_operator,
1295 Rule::repeat_operator,
1296 Rule::repeat_once_operator
1297 ],
1298 negatives: vec![],
1299 pos: 9
1300 };
1301 }
1302
1303 #[test]
1304 fn missing_term() {
1305 fails_with! {
1306 parser: PestParser,
1307 input: "a = { ! }",
1308 rule: Rule::grammar_rules,
1309 positives: vec![
1310 Rule::opening_paren,
1311 Rule::positive_predicate_operator,
1312 Rule::negative_predicate_operator,
1313 Rule::_push,
1314 Rule::peek_slice,
1315 Rule::identifier,
1316 Rule::insensitive_string,
1317 Rule::quote,
1318 Rule::single_quote
1319 ],
1320 negatives: vec![],
1321 pos: 8
1322 };
1323 }
1324
1325 #[test]
1326 fn string_missing_ending_quote() {
1327 fails_with! {
1328 parser: PestParser,
1329 input: "a = { \" }",
1330 rule: Rule::grammar_rules,
1331 positives: vec![Rule::quote],
1332 negatives: vec![],
1333 pos: 9
1334 };
1335 }
1336
1337 #[test]
1338 fn insensitive_missing_string() {
1339 fails_with! {
1340 parser: PestParser,
1341 input: "a = { ^ }",
1342 rule: Rule::grammar_rules,
1343 positives: vec![Rule::quote],
1344 negatives: vec![],
1345 pos: 8
1346 };
1347 }
1348
1349 #[test]
1350 fn char_missing_ending_single_quote() {
1351 fails_with! {
1352 parser: PestParser,
1353 input: "a = { \' }",
1354 rule: Rule::grammar_rules,
1355 positives: vec![Rule::single_quote],
1356 negatives: vec![],
1357 pos: 8
1358 };
1359 }
1360
1361 #[test]
1362 fn range_missing_range_operator() {
1363 fails_with! {
1364 parser: PestParser,
1365 input: "a = { \'a\' }",
1366 rule: Rule::grammar_rules,
1367 positives: vec![Rule::range_operator],
1368 negatives: vec![],
1369 pos: 10
1370 };
1371 }
1372
1373 #[test]
1374 fn wrong_postfix() {
1375 fails_with! {
1376 parser: PestParser,
1377 input: "a = { a& }",
1378 rule: Rule::grammar_rules,
1379 positives: vec![
1380 Rule::opening_brace,
1381 Rule::closing_brace,
1382 Rule::sequence_operator,
1383 Rule::choice_operator,
1384 Rule::optional_operator,
1385 Rule::repeat_operator,
1386 Rule::repeat_once_operator
1387 ],
1388 negatives: vec![],
1389 pos: 7
1390 };
1391 }
1392
1393 #[test]
1394 fn node_tag() {
1395 parses_to! {
1396 parser: PestParser,
1397 input: "#a = a",
1398 rule: Rule::expression,
1399 tokens: [
1400 expression(0, 6, [
1401 term(0, 6, [
1402 tag_id(0, 2),
1403 assignment_operator(3, 4),
1404 identifier(5, 6)
1405 ])
1406 ])
1407 ]
1408 };
1409 }
1410
1411 #[test]
1412 fn incomplete_node_tag() {
1413 fails_with! {
1414 parser: PestParser,
1415 input: "a = { # }",
1416 rule: Rule::grammar_rules,
1417 positives: vec![
1418 Rule::expression
1419 ],
1420 negatives: vec![],
1421 pos: 6
1422 };
1423 }
1424
1425 #[test]
1426 fn incomplete_node_tag_assignment() {
1427 fails_with! {
1428 parser: PestParser,
1429 input: "a = { #a = }",
1430 rule: Rule::grammar_rules,
1431 positives: vec![
1432 Rule::opening_paren,
1433 Rule::positive_predicate_operator,
1434 Rule::negative_predicate_operator,
1435 Rule::_push,
1436 Rule::peek_slice,
1437 Rule::identifier,
1438 Rule::insensitive_string,
1439 Rule::quote,
1440 Rule::single_quote
1441 ],
1442 negatives: vec![],
1443 pos: 11
1444 };
1445 }
1446
1447 #[test]
1448 fn incomplete_node_tag_pound_key() {
1449 fails_with! {
1450 parser: PestParser,
1451 input: "a = { a = a }",
1452 rule: Rule::grammar_rules,
1453 positives: vec![
1454 Rule::opening_brace,
1455 Rule::closing_brace,
1456 Rule::sequence_operator,
1457 Rule::choice_operator,
1458 Rule::optional_operator,
1459 Rule::repeat_operator,
1460 Rule::repeat_once_operator
1461 ],
1462 negatives: vec![],
1463 pos: 8
1464 };
1465 }
1466
1467 #[test]
1468 fn ast() {
1469 let input = r#"
1470 /// This is line comment
1471 /// This is rule
1472 rule = _{ a{1} ~ "a"{3,} ~ b{, 2} ~ "b"{1, 2} | !(^"c" | PUSH('d'..'e'))?* }
1473 "#;
1474
1475 let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1476 let ast = consume_rules_with_spans(pairs).unwrap();
1477 let ast: Vec<_> = ast.into_iter().map(convert_rule).collect();
1478
1479 assert_eq!(
1480 ast,
1481 vec![AstRule {
1482 name: "rule".to_owned(),
1483 ty: RuleType::Silent,
1484 expr: Expr::Choice(
1485 Box::new(Expr::Seq(
1486 Box::new(Expr::Seq(
1487 Box::new(Expr::Seq(
1488 Box::new(Expr::RepExact(Box::new(Expr::Ident("a".to_owned())), 1)),
1489 Box::new(Expr::RepMin(Box::new(Expr::Str("a".to_owned())), 3))
1490 )),
1491 Box::new(Expr::RepMax(Box::new(Expr::Ident("b".to_owned())), 2))
1492 )),
1493 Box::new(Expr::RepMinMax(Box::new(Expr::Str("b".to_owned())), 1, 2))
1494 )),
1495 Box::new(Expr::NegPred(Box::new(Expr::Rep(Box::new(Expr::Opt(
1496 Box::new(Expr::Choice(
1497 Box::new(Expr::Insens("c".to_owned())),
1498 Box::new(Expr::Push(Box::new(Expr::Range(
1499 "d".to_owned(),
1500 "e".to_owned()
1501 ))))
1502 ))
1503 ))))))
1504 )
1505 },]
1506 );
1507 }
1508
1509 #[test]
1510 fn ast_peek_slice() {
1511 let input = "rule = _{ PEEK[-04..] ~ PEEK[..3] }";
1512
1513 let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1514 let ast = consume_rules_with_spans(pairs).unwrap();
1515 let ast: Vec<_> = ast.into_iter().map(convert_rule).collect();
1516
1517 assert_eq!(
1518 ast,
1519 vec![AstRule {
1520 name: "rule".to_owned(),
1521 ty: RuleType::Silent,
1522 expr: Expr::Seq(
1523 Box::new(Expr::PeekSlice(-4, None)),
1524 Box::new(Expr::PeekSlice(0, Some(3))),
1525 ),
1526 }],
1527 );
1528 }
1529
1530 #[test]
1531 #[should_panic(expected = "grammar error
1532
1533 --> 1:13
1534 |
15351 | rule = { \"\"{4294967297} }
1536 | ^--------^
1537 |
1538 = number cannot overflow u32")]
1539 fn repeat_exact_overflow() {
1540 let input = "rule = { \"\"{4294967297} }";
1541
1542 let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1543 unwrap_or_report(consume_rules_with_spans(pairs));
1544 }
1545
1546 #[test]
1547 #[should_panic(expected = "grammar error
1548
1549 --> 1:13
1550 |
15511 | rule = { \"\"{0} }
1552 | ^
1553 |
1554 = cannot repeat 0 times")]
1555 fn repeat_exact_zero() {
1556 let input = "rule = { \"\"{0} }";
1557
1558 let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1559 unwrap_or_report(consume_rules_with_spans(pairs));
1560 }
1561
1562 #[test]
1563 #[should_panic(expected = "grammar error
1564
1565 --> 1:13
1566 |
15671 | rule = { \"\"{4294967297,} }
1568 | ^--------^
1569 |
1570 = number cannot overflow u32")]
1571 fn repeat_min_overflow() {
1572 let input = "rule = { \"\"{4294967297,} }";
1573
1574 let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1575 unwrap_or_report(consume_rules_with_spans(pairs));
1576 }
1577
1578 #[test]
1579 #[should_panic(expected = "grammar error
1580
1581 --> 1:14
1582 |
15831 | rule = { \"\"{,4294967297} }
1584 | ^--------^
1585 |
1586 = number cannot overflow u32")]
1587 fn repeat_max_overflow() {
1588 let input = "rule = { \"\"{,4294967297} }";
1589
1590 let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1591 unwrap_or_report(consume_rules_with_spans(pairs));
1592 }
1593
1594 #[test]
1595 #[should_panic(expected = "grammar error
1596
1597 --> 1:14
1598 |
15991 | rule = { \"\"{,0} }
1600 | ^
1601 |
1602 = cannot repeat 0 times")]
1603 fn repeat_max_zero() {
1604 let input = "rule = { \"\"{,0} }";
1605
1606 let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1607 unwrap_or_report(consume_rules_with_spans(pairs));
1608 }
1609
1610 #[test]
1611 #[should_panic(expected = "grammar error
1612
1613 --> 1:13
1614 |
16151 | rule = { \"\"{4294967297,4294967298} }
1616 | ^--------^
1617 |
1618 = number cannot overflow u32")]
1619 fn repeat_min_max_overflow() {
1620 let input = "rule = { \"\"{4294967297,4294967298} }";
1621
1622 let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1623 unwrap_or_report(consume_rules_with_spans(pairs));
1624 }
1625
1626 #[test]
1627 #[should_panic(expected = "grammar error
1628
1629 --> 1:15
1630 |
16311 | rule = { \"\"{0,0} }
1632 | ^
1633 |
1634 = cannot repeat 0 times")]
1635 fn repeat_min_max_zero() {
1636 let input = "rule = { \"\"{0,0} }";
1637
1638 let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
1639 unwrap_or_report(consume_rules_with_spans(pairs));
1640 }
1641
1642 #[test]
1643 fn unescape_all() {
1644 let string = r"a\nb\x55c\u{111}d";
1645
1646 assert_eq!(unescape(string), Some("a\nb\x55c\u{111}d".to_owned()));
1647 }
1648
1649 #[test]
1650 fn unescape_empty_escape() {
1651 let string = r"\";
1652
1653 assert_eq!(unescape(string), None);
1654 }
1655
1656 #[test]
1657 fn unescape_wrong_escape() {
1658 let string = r"\w";
1659
1660 assert_eq!(unescape(string), None);
1661 }
1662
1663 #[test]
1664 fn unescape_backslash() {
1665 let string = "\\\\";
1666 assert_eq!(unescape(string), Some("\\".to_owned()));
1667 }
1668
1669 #[test]
1670 fn unescape_return() {
1671 let string = "\\r";
1672 assert_eq!(unescape(string), Some("\r".to_owned()));
1673 }
1674
1675 #[test]
1676 fn unescape_tab() {
1677 let string = "\\t";
1678 assert_eq!(unescape(string), Some("\t".to_owned()));
1679 }
1680
1681 #[test]
1682 fn unescape_null() {
1683 let string = "\\0";
1684 assert_eq!(unescape(string), Some("\0".to_owned()));
1685 }
1686
1687 #[test]
1688 fn unescape_single_quote() {
1689 let string = "\\'";
1690 assert_eq!(unescape(string), Some("\'".to_owned()));
1691 }
1692
1693 #[test]
1694 fn unescape_wrong_byte() {
1695 let string = r"\xfg";
1696
1697 assert_eq!(unescape(string), None);
1698 }
1699
1700 #[test]
1701 fn unescape_short_byte() {
1702 let string = r"\xf";
1703
1704 assert_eq!(unescape(string), None);
1705 }
1706
1707 #[test]
1708 fn unescape_no_open_brace_unicode() {
1709 let string = r"\u11";
1710
1711 assert_eq!(unescape(string), None);
1712 }
1713
1714 #[test]
1715 fn unescape_no_close_brace_unicode() {
1716 let string = r"\u{11";
1717
1718 assert_eq!(unescape(string), None);
1719 }
1720
1721 #[test]
1722 fn unescape_short_unicode() {
1723 let string = r"\u{1}";
1724
1725 assert_eq!(unescape(string), None);
1726 }
1727
1728 #[test]
1729 fn unescape_long_unicode() {
1730 let string = r"\u{1111111}";
1731
1732 assert_eq!(unescape(string), None);
1733 }
1734
1735 #[test]
1736 fn handles_deep_nesting() {
1737 let sample1 = include_str!(concat!(
1738 env!("CARGO_MANIFEST_DIR"),
1739 "/resources/test/fuzzsample1.grammar"
1740 ));
1741 let sample2 = include_str!(concat!(
1742 env!("CARGO_MANIFEST_DIR"),
1743 "/resources/test/fuzzsample2.grammar"
1744 ));
1745 let sample3 = include_str!(concat!(
1746 env!("CARGO_MANIFEST_DIR"),
1747 "/resources/test/fuzzsample3.grammar"
1748 ));
1749 let sample4 = include_str!(concat!(
1750 env!("CARGO_MANIFEST_DIR"),
1751 "/resources/test/fuzzsample4.grammar"
1752 ));
1753 let sample5 = include_str!(concat!(
1754 env!("CARGO_MANIFEST_DIR"),
1755 "/resources/test/fuzzsample5.grammar"
1756 ));
1757 const ERROR: &str = "call limit reached";
1758 pest::set_call_limit(Some(5_000usize.try_into().unwrap()));
1759 let s1 = parse(Rule::grammar_rules, sample1);
1760 assert!(s1.is_err());
1761 assert_eq!(s1.unwrap_err().variant.message(), ERROR);
1762 let s2 = parse(Rule::grammar_rules, sample2);
1763 assert!(s2.is_err());
1764 assert_eq!(s2.unwrap_err().variant.message(), ERROR);
1765 let s3 = parse(Rule::grammar_rules, sample3);
1766 assert!(s3.is_err());
1767 assert_eq!(s3.unwrap_err().variant.message(), ERROR);
1768 let s4 = parse(Rule::grammar_rules, sample4);
1769 assert!(s4.is_err());
1770 assert_eq!(s4.unwrap_err().variant.message(), ERROR);
1771 let s5 = parse(Rule::grammar_rules, sample5);
1772 assert!(s5.is_err());
1773 assert_eq!(s5.unwrap_err().variant.message(), ERROR);
1774 }
1775}