summaryrefslogtreecommitdiffstats
path: root/vendor/pest/examples/parens.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/pest/examples/parens.rs')
-rw-r--r--vendor/pest/examples/parens.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/vendor/pest/examples/parens.rs b/vendor/pest/examples/parens.rs
new file mode 100644
index 000000000..2720f6346
--- /dev/null
+++ b/vendor/pest/examples/parens.rs
@@ -0,0 +1,75 @@
+extern crate pest;
+
+use std::io::{self, Write};
+
+use pest::error::Error;
+use pest::iterators::Pairs;
+use pest::{state, ParseResult, Parser, ParserState};
+
+#[allow(dead_code, non_camel_case_types)]
+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+enum Rule {
+ expr,
+ paren,
+ paren_end,
+}
+
+struct ParenParser;
+
+impl Parser<Rule> for ParenParser {
+ fn parse(rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
+ fn expr(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
+ state.sequence(|s| s.repeat(|s| paren(s)).and_then(|s| s.end_of_input()))
+ }
+
+ fn paren(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
+ state.rule(Rule::paren, |s| {
+ s.sequence(|s| {
+ s.match_string("(")
+ .and_then(|s| {
+ s.optional(|s| {
+ s.sequence(|s| {
+ s.lookahead(true, |s| s.match_string("("))
+ .and_then(|s| s.repeat(|s| paren(s)))
+ })
+ })
+ })
+ .and_then(|s| s.rule(Rule::paren_end, |s| s.match_string(")")))
+ })
+ })
+ }
+
+ state(input, |state| match rule {
+ Rule::expr => expr(state),
+ Rule::paren => paren(state),
+ _ => unreachable!(),
+ })
+ }
+}
+
+#[derive(Debug)]
+struct Paren(Vec<Paren>);
+
+fn expr(pairs: Pairs<Rule>) -> Vec<Paren> {
+ pairs
+ .filter(|p| p.as_rule() == Rule::paren)
+ .map(|p| Paren(expr(p.into_inner())))
+ .collect()
+}
+
+fn main() {
+ loop {
+ let mut line = String::new();
+
+ print!("> ");
+ io::stdout().flush().unwrap();
+
+ io::stdin().read_line(&mut line).unwrap();
+ line.pop();
+
+ match ParenParser::parse(Rule::expr, &line) {
+ Ok(pairs) => println!("{:?}", expr(pairs)),
+ Err(e) => println!("\n{}", e),
+ };
+ }
+}