diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 466e129d1af09590016c17f9a3b2f185dad9b668..c8266b04608df2303428520c0c40a85feb971203 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -26,6 +26,30 @@
                 "kind": "build",
                 "isDefault": true
             }
+        },
+        {
+            "type": "shell",
+            "label": "cargo run --example precedence",
+            "command": "cargo run --example precedence",
+            "problemMatcher": [
+                "$rustc"
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
+        },
+        {
+            "type": "shell",
+            "label": "cargo run --example main2",
+            "command": "cargo run --example main2",
+            "problemMatcher": [
+                "$rustc"
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
         }
     ]
 }
\ No newline at end of file
diff --git a/examples/main2.rs b/examples/main2.rs
new file mode 100644
index 0000000000000000000000000000000000000000..787e456cece35202baa429c15315da171a8e39a6
--- /dev/null
+++ b/examples/main2.rs
@@ -0,0 +1,259 @@
+extern crate nom;
+
+use nom::combinator::map_res;
+use nom::{
+    branch::alt,
+    bytes::complete::tag,
+    character::complete::{digit1, multispace0},
+    combinator::map,
+    error::{context, VerboseError, VerboseErrorKind},
+    sequence::{preceded, tuple},
+    IResult,
+};
+
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum Op {
+    Add,
+    Sub,
+    Mul,
+    Div,
+    Pow,
+}
+
+#[derive(Debug, Clone, PartialEq)]
+pub enum Expr {
+    Num(i32),
+    BinOp(Box<Expr>, Op, Box<Expr>),
+}
+
+pub fn parse_i32(i: &str) -> IResult<&str, Expr> {
+    map(digit1, |digit_str: &str| {
+        Expr::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_expr(i: &str) -> IResult<&str, Expr> {
+    preceded(
+        multispace0,
+        alt((
+            map(
+                tuple((parse_i32, preceded(multispace0, parse_op), parse_expr)),
+                |(l, op, r)| Expr::BinOp(Box::new(l), op, Box::new(r)),
+            ),
+            parse_i32,
+        )),
+    )(i)
+}
+
+fn math_expr(e: &Expr) -> String {
+    match e {
+        Expr::Num(i) => format!("{}", i),
+        Expr::BinOp(l, op, r) => format!("({} {:?} {})", math_expr(l), op, math_expr(r)),
+    }
+}
+
+fn math_eval(e: &Expr) -> i32 {
+    match e {
+        Expr::Num(i) => *i,
+        Expr::BinOp(l, op, r) => {
+            let lv = math_eval(l);
+            let rv = math_eval(r);
+            match op {
+                Op::Add => lv + rv,
+                Op::Sub => lv - rv,
+                Op::Mul => lv * rv,
+                Op::Div => lv / rv,
+                Op::Pow => lv ^ rv,
+            }
+        }
+    }
+}
+
+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),
+    }
+}
+
+fn test_clone(e: Expr) -> Expr {
+    Expr::BinOp(Box::new(e.clone()), Op::Add, Box::new(e))
+}
+
+// fn climb(e: Expr) -> Expr {
+//     println!("climb {:?}", &e);
+//     match e.clone() {
+//         Expr::Num(_) => e,
+//         Expr::BinOp(l, op, r) => {
+//             let (prec, ass) = climb_op(&op);
+
+//             // lookahead
+//             let r_new = climb(*r);
+//             match r_new.clone() {
+//                 Expr::Num(_) => Expr::BinOp(Box::new(*l), op, Box::new(r_new)),
+//                 Expr::BinOp(r_l, r_op, r_r) => {
+//                     let (r_prec, r_ass) = climb_op(&r_op);
+//                     println!(
+//                         "-- l: {:?}, r: {:?}, r_prec {}, prec {}
+//                     ",
+//                         r_l, r_r, prec, r_prec
+//                     );
+//                     if r_prec
+//                         < prec
+//                             + match r_ass {
+//                                 Ass::Left => 1,
+//                                 Ass::Right => 0,
+//                             }
+//                     {
+//                         // swap
+//                         println!("swap");
+//                         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(*r_r));
+
+//                         new_top
+//                     } else {
+//                         Expr::BinOp(Box::new(*l), op, Box::new(r_new))
+//                     }
+//                 }
+//             }
+//         }
+//     }
+// }
+
+fn climb(e: Expr) -> Expr {
+    println!("climb {:?}", &e);
+    match e.clone() {
+        Expr::Num(_) => e,
+        Expr::BinOp(l, op, r) => {
+            let (prec, ass) = climb_op(&op);
+
+            // lookahead
+            let e = match *r.clone() {
+                Expr::Num(_) => e,
+                Expr::BinOp(r_l, r_op, r_r) => {
+                    let (r_prec, r_ass) = climb_op(&r_op);
+                    println!(
+                        "-- l: {:?}, r: {:?}, r_prec {}, prec {}
+                    ",
+                        r_l, r_r, prec, r_prec
+                    );
+                    if r_prec
+                        < prec
+                            + match r_ass {
+                                Ass::Left => 1,
+                                Ass::Right => 0,
+                            }
+                    {
+                        // swap
+                        println!("swap");
+                        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(*r_r));
+
+                        climb(new_top)
+                    } else {
+                        e
+                    }
+                }
+            };
+            
+            match e {
+                Expr::Num(_) => e,
+                Expr::BinOp(l, op, r) => Expr::BinOp(l, op, Box::new(climb(*r)))
+            }
+        }
+    }
+}
+
+fn test_eq(s:&str, v:i32) {
+    assert_eq!(math_eval(&climb(parse_expr(s).unwrap().1)), v);    
+}
+
+#[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);
+}
+
+fn main() {
+    let p = parse_expr("3*2+5").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), 3 * 2 + 5);
+
+    println!();
+    let p = parse_expr("3+2*5").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), 3 + 2 * 5);
+
+    println!();
+    let p = parse_expr("3+2*5+27").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), 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);
+}