From 218caa410aa38c29984be31a5229b9fa717560ee Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:13 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- vendor/pest_derive/examples/calc.rs | 109 ++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 vendor/pest_derive/examples/calc.rs (limited to 'vendor/pest_derive/examples/calc.rs') diff --git a/vendor/pest_derive/examples/calc.rs b/vendor/pest_derive/examples/calc.rs new file mode 100644 index 000000000..efc6b7b22 --- /dev/null +++ b/vendor/pest_derive/examples/calc.rs @@ -0,0 +1,109 @@ +mod parser { + use pest_derive::Parser; + + #[derive(Parser)] + #[grammar = "../examples/calc.pest"] + pub struct Parser; +} + +use parser::Rule; +use pest::{ + iterators::Pairs, + pratt_parser::{Assoc::*, Op, PrattParser}, + Parser, +}; +use std::io::{stdin, stdout, Write}; + +fn parse_to_str(pairs: Pairs, pratt: &PrattParser) -> String { + pratt + .map_primary(|primary| match primary.as_rule() { + Rule::int => primary.as_str().to_owned(), + Rule::expr => parse_to_str(primary.into_inner(), pratt), + _ => unreachable!(), + }) + .map_prefix(|op, rhs| match op.as_rule() { + Rule::neg => format!("(-{})", rhs), + _ => unreachable!(), + }) + .map_postfix(|lhs, op| match op.as_rule() { + Rule::fac => format!("({}!)", lhs), + _ => unreachable!(), + }) + .map_infix(|lhs, op, rhs| match op.as_rule() { + Rule::add => format!("({}+{})", lhs, rhs), + Rule::sub => format!("({}-{})", lhs, rhs), + Rule::mul => format!("({}*{})", lhs, rhs), + Rule::div => format!("({}/{})", lhs, rhs), + Rule::pow => format!("({}^{})", lhs, rhs), + _ => unreachable!(), + }) + .parse(pairs) +} + +fn parse_to_i32(pairs: Pairs, pratt: &PrattParser) -> i128 { + pratt + .map_primary(|primary| match primary.as_rule() { + Rule::int => primary.as_str().parse().unwrap(), + Rule::expr => parse_to_i32(primary.into_inner(), pratt), + _ => unreachable!(), + }) + .map_prefix(|op, rhs| match op.as_rule() { + Rule::neg => -rhs, + _ => unreachable!(), + }) + .map_postfix(|lhs, op| match op.as_rule() { + Rule::fac => (1..lhs + 1).product(), + _ => unreachable!(), + }) + .map_infix(|lhs, op, rhs| match op.as_rule() { + Rule::add => lhs + rhs, + Rule::sub => lhs - rhs, + Rule::mul => lhs * rhs, + Rule::div => lhs / rhs, + Rule::pow => (1..rhs + 1).map(|_| lhs).product(), + _ => unreachable!(), + }) + .parse(pairs) +} + +fn main() { + let pratt = PrattParser::new() + .op(Op::infix(Rule::add, Left) | Op::infix(Rule::sub, Left)) + .op(Op::infix(Rule::mul, Left) | Op::infix(Rule::div, Left)) + .op(Op::infix(Rule::pow, Right)) + .op(Op::postfix(Rule::fac)) + .op(Op::prefix(Rule::neg)); + + let stdin = stdin(); + let mut stdout = stdout(); + + loop { + let source = { + print!("> "); + let _ = stdout.flush(); + let mut input = String::new(); + let _ = stdin.read_line(&mut input); + input.trim().to_string() + }; + + let pairs = match parser::Parser::parse(Rule::program, &source) { + Ok(mut parse_tree) => { + parse_tree + .next() + .unwrap() + .into_inner() // inner of program + .next() + .unwrap() + .into_inner() // inner of expr + } + Err(err) => { + println!("Failed parsing input: {:}", err); + continue; + } + }; + + print!("{} => ", source); + print!("{} => ", parse_to_str(pairs.clone(), &pratt)); + println!("{}", parse_to_i32(pairs.clone(), &pratt)); + } +} -- cgit v1.2.3