diff --git a/examples/main5.rs b/examples/main5.rs
index ca37cd4133b59570e0c82785b3ca31b2e6dcb987..7b41a4bbcd6b96c32c53a8f79f1cb25bbe21306c 100644
--- a/examples/main5.rs
+++ b/examples/main5.rs
@@ -21,41 +21,36 @@ pub enum Op {
     Mul,
     Div,
     Pow,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq)]
-pub enum UOp {
     Minus,
     Not,
+    Par
 }
 
 #[derive(Debug, Clone, PartialEq)]
 pub enum Expr {
-    Num(i32),
+    Atom(Atom),
     BinOp(Op, Box<Expr>, Box<Expr>),
-    Unary(UOp, Box<Expr>),
+    Unary(Op, Box<Expr>),
 }
 
+#[derive(Debug, Clone, PartialEq)]
+pub enum Atom {
+    Num(i32),
+    // Identifier
+    // Function application
+}
+
+
 pub fn parse_i32(i: &str) -> IResult<&str, Expr> {
     map(digit1, |digit_str: &str| {
-        Expr::Num(digit_str.parse::<i32>().unwrap())
+        Expr::Atom(Atom::Num(digit_str.parse::<i32>().unwrap()))
     })(i)
 }
 
-fn parse_op(i: &str) -> IResult<&str, Op> {
-    alt((
-        map(tag("+"), |_| Op::Add),
-        map(tag("-"), |_| Op::Sub),
-        map(tag("*"), |_| Op::Mul),
-        map(tag("/"), |_| Op::Div),
-        map(tag("^"), |_| Op::Pow),
-    ))(i)
-}
-
-fn parse_uop(i: &str) -> IResult<&str, UOp> {
+fn parse_uop(i: &str) -> IResult<&str, Op> {
     preceded(
         multispace0,
-        alt((map(tag("-"), |_| UOp::Minus), map(tag("!"), |_| UOp::Not))),
+        alt((map(tag("-"), |_| Op::Minus), map(tag("!"), |_| Op::Not))),
     )(i)
 }
 
@@ -91,30 +86,46 @@ fn parse_additative(i: &str) -> IResult<&str, Expr> {
             many0(tuple((parse_addop, parse_multiplicative))),
         )),
         |(t, m)| {
-            println!("add: t {:?}, m {:?}", t, m);
-            let r = m.iter().fold(t, |l, (op, r)| {
-                println!("l {:?}, r {:?}", l, r);
-                Expr::BinOp(*op, Box::new(l), Box::new(r.clone()))
-            });
-            r
+            m.iter()
+                .fold(t, |l, (op, r)| climb(l, op.clone(), r.clone()))
         },
     )(i)
 }
 
+fn binop(op: Op, l: Expr, r: Expr) -> Expr {
+    Expr::BinOp(op, Box::new(l), Box::new(r))
+}
+
+fn climb(l: Expr, op: Op, r: Expr) -> Expr {
+    match r.clone() {
+        Expr::BinOp(r_op, r_l, r_r) => {
+            let (prec, ass) = climb_op(&op);
+            let (r_prec, _) = climb_op(&r_op);
+            if r_prec
+                < prec
+                    + match ass {
+                        Ass::Left => 1,
+                        _ => 0,
+                    }
+            {
+                binop(r_op, binop(op, l, *r_l), *r_r)
+            } else {
+                binop(op, l, r)
+            }
+        }
+        _ => binop(op, l, r),
+    }
+}
+
 fn parse_multiplicative(i: &str) -> IResult<&str, Expr> {
-    //map(tuple((parse_terminal, opt(parse_rhs)), |((_,t), _)| t))(i)
     map(
         tuple((
             parse_terminal,
             many0(tuple((parse_mulop, parse_multiplicative))),
         )),
         |(t, m)| {
-            println!("mul: t {:?}, m {:?}", t, m);
-            let r = m.iter().fold(t, |l, (op, r)| {
-                println!("l {:?}, r {:?}", l, r);
-                Expr::BinOp(*op, Box::new(l), Box::new(r.clone()))
-            });
-            r
+            m.iter()
+                .fold(t, |l, (op, r)| climb(l, op.clone(), r.clone()))
         },
     )(i)
 }
@@ -127,15 +138,13 @@ fn parse_terminal(i: &str) -> IResult<&str, Expr> {
             map(tuple((parse_uop, parse_terminal)), |(uop, e)| {
                 Expr::Unary(uop, Box::new(e))
             }),
-            parse_parenthesis(parse_expr),
+            map(parse_parenthesis(parse_expr), |e| Expr::Unary(Op::Par, Box::new(e)))
         )),
     )(i)
 }
 
 // helpers
-fn parse_parenthesis<'a, O, F, E>(
-    inner: F,
-) -> impl Fn(&'a str) -> IResult<&'a str, O, E>
+fn parse_parenthesis<'a, O, F, E>(inner: F) -> impl Fn(&'a str) -> IResult<&'a str, O, E>
 where
     F: Fn(&'a str) -> IResult<&'a str, O, E>,
     E: ParseError<&'a str>,
@@ -146,26 +155,24 @@ where
 }
 
 fn main() {
-    let p = parse_additative("(1+2)*(5-1-1)").unwrap().1;
-    println!("{:?} {} {}", p, math_eval(&p), (1 + 2) * (5 - 1 - 1));
+    let p = parse_additative("1-(1+1)-1)").unwrap().1;
+    println!("{:?} {} {}", p, math_eval(&p), 1-(1+1)-1);
 
-    let p = parse_additative("5*(20+2)/4").unwrap().1;
-    println!("{:?} {} {}", p, math_eval(&p), 5 * (20 + 2) / 4);
+    // let p = parse_additative("5*(20+2)/4").unwrap().1;
+    // println!("{:?} {} {}", p, math_eval(&p), 5 * (20 + 2) / 4);
 }
 
 fn math_expr(e: &Expr) -> String {
     match e {
-        Expr::Num(i) => format!("{}", i),
-        Expr::BinOp(op, l, r) => {
-            format!("({:?}, {}, {})", op, math_expr(l), math_expr(r))
-        }
+        Expr::Atom(Atom::Num(i)) => format!("{}", i),
+        Expr::BinOp(op, l, r) => format!("({:?}, {}, {})", op, math_expr(l), math_expr(r)),
         Expr::Unary(op, e) => format!("({:?}, {})", op, math_expr(e)),
     }
 }
 
 fn math_eval(e: &Expr) -> i32 {
     match e {
-        Expr::Num(i) => *i,
+        Expr::Atom(Atom::Num(i)) => *i,
         Expr::BinOp(op, l, r) => {
             let lv = math_eval(l);
             let rv = math_eval(r);
@@ -177,156 +184,34 @@ fn math_eval(e: &Expr) -> i32 {
                 Op::Pow => lv.pow(rv as u32),
                 _ => unimplemented!(),
             }
+        },
+        Expr::Unary(op, e) => {
+            let e = math_eval(e);
+            match op {
+                Op::Par => e,
+                Op::Mul => -e,
+                _ => unimplemented!(),
+            }
         }
+        
         _ => unimplemented!(),
     }
 }
 
-// #[derive(Debug, Copy, Clone, PartialEq)]
-// enum Ass {
-//     Left,
-//     Right,
-// }
-
-// fn climb_op(op: &Op) -> (u8, Ass) {
-//     match op {
-//         Op::Add => (1, Ass::Left),
-//         Op::Sub => (1, Ass::Left),
-//         Op::Mul => (2, Ass::Left),
-//         Op::Div => (2, Ass::Left),
-//         Op::Pow => (3, Ass::Right),
-//     }
-// }
-
-// operator precedence parser
-// https://en.wikipedia.org/wiki/Operator-precedence_parser
-// parse_expression ()
-//     return parse_expression_1 (parse_primary (), 0)
-
-// parse_expression_1 (lhs, min_precedence)
-//     lookahead := peek next token
-//     while lookahead is a binary operator whose precedence is >= min_precedence
-//         op := lookahead
-//         advance to next token
-//         rhs := parse_primary ()
-//         lookahead := peek next token
-//         while lookahead is a binary operator whose precedence is greater
-//                  than op's, or a right-associative operator
-//                  whose precedence is equal to op's
-//             rhs := parse_expression_1 (rhs, lookahead's precedence)
-//             lookahead := peek next token
-//         lhs := the result of applying op with operands lhs and rhs
-//     return lhs
-
-// fn token_to_expr(t: Token) -> Expr {
-//     match t {
-//         Token::Num(i) => Expr::Num(i),
-//         _ => panic!(),
-//     }
-// }
-
-// fn climb(mut v: Vec<Token>, min_prec: u8) -> (Expr, Vec<Token>) {
-//     println!("in climb {:?}, {}", v, min_prec);
-//     let t = v.last().unwrap();
-//     let mut result = token_to_expr(*t);
-//     // loop {
-//     //     match v.pop() {
-//     //         Some(Token::Num(_)) => {
-//     //             println!("break num");
-//     //             break;
-//     //         }
-//     //         Some(Token::Op(op)) => {
-//     //             println!("result {:?}, op {:?}, v:{:?}", result, op, v);
-//     //             let (prec, assoc) = climb_op(&op);
-//     //             if prec < min_prec {
-//     //                 println!("break prec");
-//     //                 break;
-//     //             } else {
-//     //                 println!("push");
-//     //                 let next_min_prec =
-//     //                     if assoc == Ass::Left { 1 + prec } else { prec };
-//     //                 let (rhs, v_rest) = climb(v.clone(), next_min_prec);
-//     //                 v = v_rest;
-//     //                 println!("return from call, rhs {:?}, v {:?}", rhs, v);
-//     //                 println!("current result {:?}", result);
-//     //                 result = Expr::BinOp(Box::new(result), op, Box::new(rhs));
-//     //                 println!("new result {:?}", result);
-//     //             }
-//     //         }
-
-//     //         _ => {
-//     //             println!("reaced end");
-//     //             break;
-//     //         } // reached end
-//     //     }
-//     // }
-//     (result, v)
-// }
-
-// fn test_eq(s: &str, v: i32) {
-//     let mut p = parse_expr(s).unwrap().1;
-//     println!("{:?}", p);
-//     p.reverse();
-//     let e = climb(p, 0);
-//     println!("{:?}", e);
-
-//     println!("e = {}, v = {}", math_eval(&e.0), v);
-// }
-
-// fn main() {
-//     test_eq("1 + 2", 1 + 2);
-//     // test_eq("1 + 2 * 3", 1 + 2 * 3);
-//     // test_eq("3 * 4 + 5", 3 * 4 + 5);
-
-//     //     // 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-2+12", 2*5+10*11-1+12);
-//     //     // climb_test("1+2*3-4+5", 1 + 2 * 3 - 4 + 5);
-//     //     climb_test("1", 1);
-//     //     climb_test("1+2", 1 + 2);
-// }
-
-// // // #[test]
-// // // fn climb1() {
-// // //     test_eq("1-2+3", 1 - 2 + 3);
-// // // }
-
-// // // #[test]
-// // // fn climb2() {
-// // //     test_eq("1*2+3", 1 * 2 + 3);
-// // // }
-
-// // // #[test]
-// // // fn climb3() {
-// // //     test_eq("1*2+3*4-5", 1 * 2 + 3 * 4 - 5);
-// // // }
-
-// // // #[test]
-// // // fn climb4() {
-// // //     test_eq("2^5", 2i32.pow(5));
-// // // }
-
-// // // #[test]
-// // // fn climb5() {
-// // //     test_eq("2*3+4+5", 2 * 3 + 4 + 5);
-// // // }
-
-// // // #[test]
-// // // fn climb6() {
-// // //     test_eq("2*3-4*5-2", 2 * 3 - 4 * 5 - 2);
-// // // }
+#[derive(Debug, Copy, Clone, PartialEq)]
+enum Ass {
+    Left,
+    Right,
+}
 
-// // // #[test]
-// // // fn climb_err() {
-// // //     test_eq("2 + 2 ^ 5 -3", 2 + 2i32.pow(5 - 3));
-// // // }
+fn climb_op(op: &Op) -> (u8, Ass) {
+    match op {
+        Op::Add => (1, Ass::Left),
+        Op::Sub => (1, Ass::Left),
+        Op::Mul => (2, Ass::Left),
+        Op::Div => (2, Ass::Left),
+        Op::Pow => (3, Ass::Right),
+        _ => unimplemented!(),
+    }
+}
 
-// // fn climb_test(s: &str, v: i32) {
-// //     let p = parse_expr(s).unwrap().1;
-// //     println!("{:?}", &p);
-// //     println!("math {}\n", math_expr(&p));
-// //     let r = climb(p, 0);
-// //     println!("r {:?}", &r);
-// //     println!("math r {}", math_expr(&r));
-// //     println!("eval r {} = {} ", math_eval(&r), v);
-// // }