summaryrefslogtreecommitdiffstats
path: root/vendor/pest_meta/src/parser.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:31 +0000
commitdc0db358abe19481e475e10c32149b53370f1a1c (patch)
treeab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/pest_meta/src/parser.rs
parentReleasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff)
downloadrustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz
rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip
Merging upstream version 1.72.1+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.rs146
1 files changed, 129 insertions, 17 deletions
diff --git a/vendor/pest_meta/src/parser.rs b/vendor/pest_meta/src/parser.rs
index eb957a163..a4e8d1b33 100644
--- a/vendor/pest_meta/src/parser.rs
+++ b/vendor/pest_meta/src/parser.rs
@@ -15,20 +15,18 @@ use std::iter::Peekable;
use pest::error::{Error, ErrorVariant};
use pest::iterators::{Pair, Pairs};
use pest::pratt_parser::{Assoc, Op, PrattParser};
-use pest::{Parser, Span};
+use pest::{Parser, Position, Span};
use crate::ast::{Expr, Rule as AstRule, RuleType};
use crate::validator;
-/// TODO: fix the generator to at least add explicit lifetimes
-#[allow(
- missing_docs,
- unused_attributes,
- elided_lifetimes_in_paths,
- unused_qualifications
-)]
+#[allow(missing_docs, unused_qualifications)]
mod grammar {
+ #[cfg(not(feature = "not-bootstrap-in-src"))]
include!("grammar.rs");
+
+ #[cfg(feature = "not-bootstrap-in-src")]
+ include!(concat!(env!("OUT_DIR"), "/__pest_grammar.rs"));
}
pub use self::grammar::*;
@@ -76,7 +74,6 @@ impl<'i> ParserNode<'i> {
}
match node.expr {
- // TODO: Use box syntax when it gets stabilized.
ParserExpr::PosPred(node) => {
filter_internal(*node, f, result);
}
@@ -164,6 +161,9 @@ pub enum ParserExpr<'i> {
RepMinMax(Box<ParserNode<'i>>, u32, u32),
/// Matches an expression and pushes it to the stack, e.g. `push(e)`
Push(Box<ParserNode<'i>>),
+ /// Matches an expression and assigns a label to it, e.g. #label = exp
+ #[cfg(feature = "grammar-extras")]
+ NodeTag(Box<ParserNode<'i>>, String),
}
fn convert_rule(rule: ParserRule<'_>) -> AstRule {
@@ -199,6 +199,8 @@ fn convert_node(node: ParserNode<'_>) -> Expr {
Expr::RepMinMax(Box::new(convert_node(*node)), min, max)
}
ParserExpr::Push(node) => Expr::Push(Box::new(convert_node(*node))),
+ #[cfg(feature = "grammar-extras")]
+ ParserExpr::NodeTag(node, tag) => Expr::NodeTag(Box::new(convert_node(*node)), tag),
}
}
@@ -305,6 +307,29 @@ fn consume_rules_with_spans(
.collect()
}
+fn get_node_tag<'i>(
+ pairs: &mut Peekable<Pairs<'i, Rule>>,
+) -> (Pair<'i, Rule>, Option<(String, Position<'i>)>) {
+ let pair_or_tag = pairs.next().unwrap();
+ if let Some(next_pair) = pairs.peek() {
+ if next_pair.as_rule() == Rule::assignment_operator {
+ pairs.next().unwrap();
+ let pair = pairs.next().unwrap();
+ (
+ pair,
+ Some((
+ pair_or_tag.as_str()[1..].to_string(),
+ pair_or_tag.as_span().start_pos(),
+ )),
+ )
+ } else {
+ (pair_or_tag, None)
+ }
+ } else {
+ (pair_or_tag, None)
+ }
+}
+
fn consume_expr<'i>(
pairs: Peekable<Pairs<'i, Rule>>,
pratt: &PrattParser<Rule>,
@@ -313,7 +338,10 @@ fn consume_expr<'i>(
mut pairs: Peekable<Pairs<'i, Rule>>,
pratt: &PrattParser<Rule>,
) -> Result<ParserNode<'i>, Vec<Error<Rule>>> {
- let pair = pairs.next().unwrap();
+ #[cfg(feature = "grammar-extras")]
+ let (pair, tag_start) = get_node_tag(&mut pairs);
+ #[cfg(not(feature = "grammar-extras"))]
+ let (pair, _tag_start) = get_node_tag(&mut pairs);
let node = match pair.as_rule() {
Rule::opening_paren => {
@@ -370,7 +398,7 @@ fn consume_expr<'i>(
pairs.next().unwrap(); // ..
pair_start.as_str().parse().unwrap()
}
- _ => unreachable!(),
+ _ => unreachable!("peek start"),
};
let pair_end = pairs.next().unwrap(); // integer or }
let end: Option<i32> = match pair_end.as_rule() {
@@ -379,7 +407,7 @@ fn consume_expr<'i>(
pairs.next().unwrap(); // }
Some(pair_end.as_str().parse().unwrap())
}
- _ => unreachable!(),
+ _ => unreachable!("peek end"),
};
ParserNode {
expr: ParserExpr::PeekSlice(start, end),
@@ -422,7 +450,7 @@ fn consume_expr<'i>(
span: start_pos.span(&end_pos),
}
}
- _ => unreachable!(),
+ x => unreachable!("other rule: {:?}", x),
};
pairs.fold(
@@ -600,7 +628,7 @@ fn consume_expr<'i>(
span: start.span(&pair.as_span().end_pos()),
}
}
- _ => unreachable!(),
+ rule => unreachable!("node: {:?}", rule),
};
Ok(node)
@@ -608,7 +636,17 @@ fn consume_expr<'i>(
)?
}
};
-
+ #[cfg(feature = "grammar-extras")]
+ if let Some((tag, start)) = tag_start {
+ let span = start.span(&node.span.end_pos());
+ Ok(ParserNode {
+ expr: ParserExpr::NodeTag(Box::new(node), tag),
+ span,
+ })
+ } else {
+ Ok(node)
+ }
+ #[cfg(not(feature = "grammar-extras"))]
Ok(node)
}
@@ -640,7 +678,7 @@ fn consume_expr<'i>(
span: start.span(&end),
})
}
- _ => unreachable!(),
+ _ => unreachable!("infix"),
};
pratt.map_primary(term).map_infix(infix).parse(pairs)
@@ -1143,7 +1181,7 @@ mod tests {
parser: PestParser,
input: "0",
rule: Rule::grammar_rules,
- positives: vec![Rule::grammar_rule, Rule::grammar_doc],
+ positives: vec![Rule::EOI, Rule::grammar_rule, Rule::grammar_doc],
negatives: vec![],
pos: 0
};
@@ -1358,6 +1396,80 @@ mod tests {
}
#[test]
+ fn node_tag() {
+ parses_to! {
+ parser: PestParser,
+ input: "#a = a",
+ rule: Rule::expression,
+ tokens: [
+ expression(0, 6, [
+ term(0, 6, [
+ tag_id(0, 2),
+ assignment_operator(3, 4),
+ identifier(5, 6)
+ ])
+ ])
+ ]
+ };
+ }
+
+ #[test]
+ fn incomplete_node_tag() {
+ fails_with! {
+ parser: PestParser,
+ input: "a = { # }",
+ rule: Rule::grammar_rules,
+ positives: vec![
+ Rule::expression
+ ],
+ negatives: vec![],
+ pos: 6
+ };
+ }
+
+ #[test]
+ fn incomplete_node_tag_assignment() {
+ fails_with! {
+ parser: PestParser,
+ input: "a = { #a = }",
+ rule: Rule::grammar_rules,
+ positives: vec![
+ Rule::opening_paren,
+ Rule::positive_predicate_operator,
+ Rule::negative_predicate_operator,
+ Rule::_push,
+ Rule::peek_slice,
+ Rule::identifier,
+ Rule::insensitive_string,
+ Rule::quote,
+ Rule::single_quote
+ ],
+ negatives: vec![],
+ pos: 11
+ };
+ }
+
+ #[test]
+ fn incomplete_node_tag_pound_key() {
+ fails_with! {
+ parser: PestParser,
+ input: "a = { a = a }",
+ rule: Rule::grammar_rules,
+ positives: vec![
+ Rule::opening_brace,
+ Rule::closing_brace,
+ Rule::sequence_operator,
+ Rule::choice_operator,
+ Rule::optional_operator,
+ Rule::repeat_operator,
+ Rule::repeat_once_operator
+ ],
+ negatives: vec![],
+ pos: 8
+ };
+ }
+
+ #[test]
fn ast() {
let input = r##"
/// This is line comment