summaryrefslogtreecommitdiffstats
path: root/vendor/pest_meta/src/parser.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:03:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:03:36 +0000
commit17d40c6057c88f4c432b0d7bac88e1b84cb7e67f (patch)
tree3f66c4a5918660bb8a758ab6cda5ff8ee4f6cdcd /vendor/pest_meta/src/parser.rs
parentAdding upstream version 1.64.0+dfsg1. (diff)
downloadrustc-f7f0cc2a5d72e2c61c1f6900e70eec992bea4273.tar.xz
rustc-f7f0cc2a5d72e2c61c1f6900e70eec992bea4273.zip
Adding upstream version 1.65.0+dfsg1.upstream/1.65.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/pest_meta/src/parser.rs')
-rw-r--r--vendor/pest_meta/src/parser.rs93
1 files changed, 76 insertions, 17 deletions
diff --git a/vendor/pest_meta/src/parser.rs b/vendor/pest_meta/src/parser.rs
index 5f6f3b374..72abd810d 100644
--- a/vendor/pest_meta/src/parser.rs
+++ b/vendor/pest_meta/src/parser.rs
@@ -15,10 +15,14 @@ use pest::iterators::{Pair, Pairs};
use pest::prec_climber::{Assoc, Operator, PrecClimber};
use pest::{Parser, Span};
-use ast::{Expr, Rule as AstRule, RuleType};
-use validator;
+use crate::ast::{Expr, Rule as AstRule, RuleType};
+use crate::validator;
-include!("grammar.rs");
+mod grammar {
+ include!("grammar.rs");
+}
+
+pub use self::grammar::*;
pub fn parse(rule: Rule, data: &str) -> Result<Pairs<Rule>, Error<Rule>> {
PestParser::parse(rule, data)
@@ -125,13 +129,9 @@ pub enum ParserExpr<'i> {
}
fn convert_rule(rule: ParserRule) -> AstRule {
- match rule {
- ParserRule { name, ty, node, .. } => {
- let expr = convert_node(node);
-
- AstRule { name, ty, expr }
- }
- }
+ let ParserRule { name, ty, node, .. } = rule;
+ let expr = convert_node(node);
+ AstRule { name, ty, expr }
}
fn convert_node(node: ParserNode) -> Expr {
@@ -174,9 +174,7 @@ pub fn consume_rules(pairs: Pairs<Rule>) -> Result<Vec<AstRule>, Vec<Error<Rule>
}
}
-fn consume_rules_with_spans<'i>(
- pairs: Pairs<'i, Rule>,
-) -> Result<Vec<ParserRule<'i>>, Vec<Error<Rule>>> {
+fn consume_rules_with_spans(pairs: Pairs<Rule>) -> Result<Vec<ParserRule>, Vec<Error<Rule>>> {
let climber = PrecClimber::new(vec![
Operator::new(Rule::choice_operator, Assoc::Left),
Operator::new(Rule::sequence_operator, Assoc::Left),
@@ -206,7 +204,13 @@ fn consume_rules_with_spans<'i>(
pairs.next().unwrap(); // opening_brace
- let node = consume_expr(pairs.next().unwrap().into_inner().peekable(), &climber)?;
+ // skip initial infix operators
+ let mut inner_nodes = pairs.next().unwrap().into_inner().peekable();
+ if inner_nodes.peek().unwrap().as_rule() == Rule::choice_operator {
+ inner_nodes.next().unwrap();
+ }
+
+ let node = consume_expr(inner_nodes, &climber)?;
Ok(ParserRule {
name,
@@ -617,6 +621,8 @@ fn unescape(string: &str) -> Option<String> {
#[cfg(test)]
mod tests {
+ use std::convert::TryInto;
+
use super::super::unwrap_or_report;
use super::*;
@@ -1073,7 +1079,7 @@ mod tests {
parser: PestParser,
input: "a = {}",
rule: Rule::grammar_rules,
- positives: vec![Rule::term],
+ positives: vec![Rule::expression],
negatives: vec![],
pos: 5
};
@@ -1092,6 +1098,18 @@ mod tests {
}
#[test]
+ fn incorrect_prefix() {
+ fails_with! {
+ parser: PestParser,
+ input: "a = { ~ b}",
+ rule: Rule::grammar_rules,
+ positives: vec![Rule::expression],
+ negatives: vec![],
+ pos: 6
+ };
+ }
+
+ #[test]
fn wrong_op() {
fails_with! {
parser: PestParser,
@@ -1228,7 +1246,7 @@ mod tests {
let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
let ast = consume_rules_with_spans(pairs).unwrap();
- let ast: Vec<_> = ast.into_iter().map(|rule| convert_rule(rule)).collect();
+ let ast: Vec<_> = ast.into_iter().map(convert_rule).collect();
assert_eq!(
ast,
@@ -1266,7 +1284,7 @@ mod tests {
let pairs = PestParser::parse(Rule::grammar_rules, input).unwrap();
let ast = consume_rules_with_spans(pairs).unwrap();
- let ast: Vec<_> = ast.into_iter().map(|rule| convert_rule(rule)).collect();
+ let ast: Vec<_> = ast.into_iter().map(convert_rule).collect();
assert_eq!(
ast,
@@ -1485,4 +1503,45 @@ mod tests {
assert_eq!(unescape(string), None);
}
+
+ #[test]
+ fn handles_deep_nesting() {
+ let sample1 = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/resources/test/fuzzsample1.grammar"
+ ));
+ let sample2 = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/resources/test/fuzzsample2.grammar"
+ ));
+ let sample3 = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/resources/test/fuzzsample3.grammar"
+ ));
+ let sample4 = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/resources/test/fuzzsample4.grammar"
+ ));
+ let sample5 = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/resources/test/fuzzsample5.grammar"
+ ));
+ const ERROR: &str = "call limit reached";
+ pest::set_call_limit(Some(5_000usize.try_into().unwrap()));
+ let s1 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample1);
+ assert!(s1.is_err());
+ assert_eq!(s1.unwrap_err().variant.message(), ERROR);
+ let s2 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample2);
+ assert!(s2.is_err());
+ assert_eq!(s2.unwrap_err().variant.message(), ERROR);
+ let s3 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample3);
+ assert!(s3.is_err());
+ assert_eq!(s3.unwrap_err().variant.message(), ERROR);
+ let s4 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample4);
+ assert!(s4.is_err());
+ assert_eq!(s4.unwrap_err().variant.message(), ERROR);
+ let s5 = crate::parser::parse(crate::parser::Rule::grammar_rules, sample5);
+ assert!(s5.is_err());
+ assert_eq!(s5.unwrap_err().variant.message(), ERROR);
+ }
}