Skip to content
Snippets Groups Projects
Commit 7d6d08c6 authored by Per's avatar Per
Browse files

precedence wip iterative

parent f55e0a2c
No related branches found
No related tags found
No related merge requests found
...@@ -26,6 +26,18 @@ pub enum Expr { ...@@ -26,6 +26,18 @@ pub enum Expr {
BinOp(Box<Expr>, Op, Box<Expr>), BinOp(Box<Expr>, Op, Box<Expr>),
} }
// // deep cloning (is it necessary)
// impl Clone for Expr {
// fn clone(&self) -> Expr {
// match self {
// Expr::BinOp(l, op, r) => Expr::BinOp (
// l.clone(), *op, r.clone()
// ),
// Expr::Num(i) => Expr::Num(*i)
// }
// }
// }
pub fn parse_i32(i: &str) -> IResult<&str, Expr> { pub fn parse_i32(i: &str) -> IResult<&str, Expr> {
map(digit1, |digit_str: &str| { map(digit1, |digit_str: &str| {
Expr::Num(digit_str.parse::<i32>().unwrap()) Expr::Num(digit_str.parse::<i32>().unwrap())
...@@ -58,7 +70,9 @@ fn parse_expr(i: &str) -> IResult<&str, Expr> { ...@@ -58,7 +70,9 @@ fn parse_expr(i: &str) -> IResult<&str, Expr> {
fn math_expr(e: &Expr) -> String { fn math_expr(e: &Expr) -> String {
match e { match e {
Expr::Num(i) => format!("{}", i), Expr::Num(i) => format!("{}", i),
Expr::BinOp(l, op, r) => format!("({} {:?} {})", math_expr(l), op, math_expr(r)), Expr::BinOp(l, op, r) => {
format!("({:?}, {}, {})", op, math_expr(l), math_expr(r))
}
} }
} }
...@@ -94,148 +108,91 @@ fn climb_op(op: &Op) -> (u8, Ass) { ...@@ -94,148 +108,91 @@ fn climb_op(op: &Op) -> (u8, Ass) {
} }
} }
fn climb(e: Expr) -> Expr { // fn build_expr(l:&Expr, op:&Op, r:&Expr) -> Expr {
println!("climb {:?}", &e); // Expr::BinOp(Box::new(*l), *op, Box::new(*r))
// }
fn climb(e: Expr, min_prec: u8) -> Expr {
println!("in climb {}, {}", math_expr(&e), min_prec);
match e.clone() { match e.clone() {
Expr::Num(_) => e, Expr::Num(_) => e,
Expr::BinOp(l, op, r) => { Expr::BinOp(l, op, r) => {
let (prec, ass) = climb_op(&op); let (prec, ass) = climb_op(&op);
let new_r = *r;
match new_r.clone() { let mut res = e.clone();
Expr::Num(_) => e, let mut cur = e.clone();
Expr::BinOp(r_l, r_op, r_r) => { while let Expr::BinOp(l, op, r) = cur {
let (r_prec, r_ass) = climb_op(&r_op); cur = *r.clone();
if r_prec let rhs = climb(
< prec cur.clone(),
+ match ass { prec + match ass {
Ass::Left => 1, Ass::Left => 1,
Ass::Right => 0, Ass::Right => 0,
} },
{ );
// push upwards println!("rhs {}", math_expr(&rhs));
println!("push upwards {:?} {:?}", op, r_op); res = Expr::BinOp(Box::new(res), op, Box::new(rhs))
let new_l = Expr::BinOp(Box::new(*l), op, Box::new(*r_l));
let new_top = Expr::BinOp(Box::new(new_l), r_op, Box::new(climb(*r_r)));
new_top
} else {
Expr::BinOp(l, op, Box::new(climb(new_r)))
}
}
} }
res
} }
} }
} }
fn test_eq(s: &str, v: i32) { // fn test_eq(s: &str, v: i32) {
assert_eq!(math_eval(&climb(parse_expr(s).unwrap().1)), v); // assert_eq!(math_eval(&climb(parse_expr(s).unwrap().1), 0), v);
} // }
#[test] // #[test]
fn climb1() { // fn climb1() {
test_eq("1-2+3", 1 - 2 + 3); // test_eq("1-2+3", 1 - 2 + 3);
} // }
#[test] // #[test]
fn climb2() { // fn climb2() {
test_eq("1*2+3", 1 * 2 + 3); // test_eq("1*2+3", 1 * 2 + 3);
} // }
#[test] // #[test]
fn climb3() { // fn climb3() {
test_eq("1*2+3*4-5", 1 * 2 + 3 * 4 - 5); // test_eq("1*2+3*4-5", 1 * 2 + 3 * 4 - 5);
} // }
#[test] // #[test]
fn climb4() { // fn climb4() {
test_eq("2^5", 2i32.pow(5)); // test_eq("2^5", 2i32.pow(5));
} // }
#[test] // #[test]
fn climb5() { // fn climb5() {
test_eq("2*3+4+5", 2 * 3 + 4 + 5); // test_eq("2*3+4+5", 2 * 3 + 4 + 5);
} // }
#[test] // #[test]
fn climb6() { // fn climb6() {
test_eq("2*3-4*5-2", 2 * 3 - 4 * 5 - 2); // test_eq("2*3-4*5-2", 2 * 3 - 4 * 5 - 2);
} // }
#[test] // #[test]
fn climb_err() { // fn climb_err() {
test_eq("2 + 2 ^ 5 -3", 2 + 2i32.pow(5 - 3)); // test_eq("2 + 2 ^ 5 -3", 2 + 2i32.pow(5 - 3));
} // }
fn climb_test(s: &str, v: i32) { fn climb_test(s: &str, v: i32) {
let p = parse_expr(s).unwrap().1; let p = parse_expr(s).unwrap().1;
println!("{:?}", &p); println!("{:?}", &p);
println!("math {}", math_expr(&p)); println!("math {}", math_expr(&p));
let r = climb(p); let r = climb(p, 0);
println!("r {:?}", &r); println!("r {:?}", &r);
println!("math r {}", math_expr(&r)); println!("math r {}", math_expr(&r));
println!("eval r {} = {} ", math_eval(&r), v); println!("eval r {} = {} ", math_eval(&r), v);
} }
fn main() { fn main() {
climb_test("2*5+10+10", 2*5+10+10); // climb_test("2*5+10+10", 2*5+10+10);
climb_test("2*5+10*11-1", 2*5+10*11-1); // climb_test("2*5+10*11-1", 2*5+10*11-1);
climb_test("2*5+10*11-2+12", 2*5+10*11-1+12); // climb_test("2*5+10*11-2+12", 2*5+10*11-1+12);
// println!(); // climb_test("1+2*3-4+5", 1 + 2 * 3 - 4 + 5);
// let p = parse_expr("3+2*5+27").unwrap().1; climb_test("1", 1);
// println!("{:?}", &p); climb_test("1+2", 1 + 2);
// println!("math {}", math_expr(&p));
// let r = climb(p);
// println!("r {:?}", &r);
// println!("math r {}", math_expr(&r));
// println!("eval r {} = {} ", math_eval(&r), 3 + 2 * 5 + 27);
// println!();
// let p = parse_expr("2*5+11*27+13").unwrap().1;
// println!("{:?}", &p);
// println!("math {}", math_expr(&p));
// let r = climb(p);
// println!("r {:?}", &r);
// println!("math r {}", math_expr(&r));
// println!("eval r {} = {} ", math_eval(&r), 2 * 5 + 11 * 27 + 13);
// println!();
// let p = parse_expr("1-2-3").unwrap().1;
// println!("{:?}", &p);
// println!("math {}", math_expr(&p));
// let r = climb(p);
// println!("r {:?}", &r);
// println!("math r {}", math_expr(&r));
// println!("eval r {} = {} ", math_eval(&r), 1 - 2 - 3);
// let i = "1-2-3-4";
// println!("\n{}", i);
// let p = parse_expr(i).unwrap().1;
// println!("{:?}", &p);
// println!("math {}", math_expr(&p));
// println!("eval r {} = {} ", math_eval(&p), 1 - 2 - 3 - 4);
// let r = climb(p);
// println!("r {:?}", &r);
// println!("math r {}", math_expr(&r));
// println!("eval r {} = {} ", math_eval(&r), ((1 - 2) - 3) - 4);
// let i = "2*3-4*5-2";
// println!("\n{}", i);
// let p = parse_expr(i).unwrap().1;
// println!("{:?}", &p);
// println!("math {}", math_expr(&p));
// println!("eval r {} = {} ", math_eval(&p), 2 * 3 - 4 * 5 - 2);
// let r = climb(p);
// println!("r {:?}", &r);
// println!("math r {}", math_expr(&r));
// println!("eval r {} = {} ", math_eval(&r), (2 * 3) - (4 * 5) - 2);
// let i = "2^5-1";
// println!("\n{}", i);
// let p = parse_expr(i).unwrap().1;
// println!("{:?}", &p);
// println!("math {}", math_expr(&p));
// println!("eval r {} = {} ", math_eval(&p), 1 - 2 - 3 - 4);
// let r = climb(p);
// println!("r {:?}", &r);
// println!("math r {}", math_expr(&r));
// println!("eval r {} = {} ", math_eval(&r), ((1 - 2) - 3) - 4);
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment