diff --git a/examples/main2.rs b/examples/main2.rs
index e513364198a156282aebc871dcdd7bce124c9441..7270d7a6e95c025aa76234d3e04a5291f68eb608 100644
--- a/examples/main2.rs
+++ b/examples/main2.rs
@@ -94,39 +94,31 @@ fn climb_op(op: &Op) -> (u8, Ass) {
     }
 }
 
-
 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
-            match *r.clone() {
+            let new_r = *r;
+            match new_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 {
+                            + match ass {
                                 Ass::Left => 1,
                                 Ass::Right => 0,
                             }
                     {
-                        // swap
-                        println!("swap");
+                        // push upwards
+                        println!("push upwards {:?} {:?}", op, r_op);
                         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)
+                        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(*r)))
+                        Expr::BinOp(l, op, Box::new(climb(new_r)))
                     }
                 }
             }
@@ -160,12 +152,12 @@ fn climb4() {
 
 #[test]
 fn climb5() {
-    test_eq("2*3+4+5", 2*3+4+5);
+    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);
+    test_eq("2*3-4*5-2", 2 * 3 - 4 * 5 - 2);
 }
 
 #[test]
@@ -173,74 +165,77 @@ fn climb_err() {
     test_eq("2 + 2 ^ 5 -3", 2 + 2i32.pow(5 - 3));
 }
 
-
-fn main() {
-    println!("{}", 2^5);
-    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;
+fn climb_test(s: &str, v: i32) {
+    let p = parse_expr(s).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);
-
-    
-    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);
+    println!("eval r {} = {} ", math_eval(&r), v);
+}
 
+fn main() {
+    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);
+    // 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);
+
+    // 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);
 }
diff --git a/examples/main3.rs b/examples/main3.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7ae13827b0873f6d007ebd88fe9c388cd78fb402
--- /dev/null
+++ b/examples/main3.rs
@@ -0,0 +1,333 @@
+use nom::{branch, bytes::complete::tag, character::complete::digit1, error, Err};
+use nom_locate::LocatedSpan;
+
+const INPUT: &str = "-2+3**2*3/5-4";
+//const INPUT: &str = "2+-3";
+//const INPUT: &str = "2+30000000000000000000000";
+//const INPUT: &str = "2";
+//const INPUT: &str = "30000000000000000000000";
+//const INPUT: &str = "3+2a";
+
+const UNARYS: [Funcmap; 1] = [Funcmap {
+    keyword: "-",
+    prec: 4,
+    ass: Ass::Right,
+    func: Function::UnSub,
+}];
+
+const INFIXS: [Funcmap; 5] = [
+    Funcmap {
+        keyword: "**",
+        prec: 3,
+        ass: Ass::Right,
+        func: Function::Pow,
+    },
+    Funcmap {
+        keyword: "*",
+        prec: 2,
+        ass: Ass::Left,
+        func: Function::Mult,
+    },
+    Funcmap {
+        keyword: "/",
+        prec: 2,
+        ass: Ass::Left,
+        func: Function::Div,
+    },
+    Funcmap {
+        keyword: "+",
+        prec: 1,
+        ass: Ass::Left,
+        func: Function::Add,
+    },
+    Funcmap {
+        keyword: "-",
+        prec: 1,
+        ass: Ass::Left,
+        func: Function::Sub,
+    },
+];
+
+struct Expr<'a> {
+    span: Span<'a>,
+    val: Value<'a>,
+}
+
+enum Value<'a> {
+    Int(i32),
+    UnFunc(Function, Box<Expr<'a>>),
+    Func(Function, Box<Expr<'a>>, Box<Expr<'a>>),
+}
+
+#[derive(Clone, Copy)]
+enum Function {
+    UnSub,
+    Pow,
+    Mult,
+    Div,
+    Add,
+    Sub,
+}
+
+struct Funcmap {
+    keyword: &'static str,
+    prec: u8,
+    ass: Ass,
+    func: Function,
+}
+
+enum Ass {
+    Left,
+    Right,
+}
+
+type Span<'a> = LocatedSpan<&'a str>;
+type SpanFuncmap<'a> = (Span<'a>, &'a Funcmap);
+type IResult<'a, I, O, E = Error<'a>> = Result<(I, O), Err<E>>;
+
+fn main() {
+    match parse(Span::new(INPUT)) {
+        Ok(tree) => {
+            println!("{:#?}", SimpleExpr::new(&tree));
+        }
+        Err(Error {
+            val: Some(val),
+            error,
+            ..
+        }) => println!(
+            "{:#?} at line {}, column {}:\n\t{}",
+            error.description(),
+            val.line,
+            val.get_utf8_column(),
+            val.fragment,
+        ),
+        Err(err) => panic!(err),
+    }
+}
+
+fn parse<'a>(input: Span) -> Result<Expr, Error> {
+    match parse_expr(input) {
+        Ok((Span { fragment: "", .. }, tree)) => Ok(tree),
+        Ok((input, _)) => Err(Error {
+            input: input,
+            val: Some(input),
+            error: ErrorKind::NotRecognised,
+        }),
+        Err(Err::Incomplete(_)) => Err(Error {
+            input: input,
+            val: Some(input),
+            error: ErrorKind::Incomplete,
+        }),
+        Err(Err::Error(err)) => Err(err),
+        Err(Err::Failure(err)) => Err(err),
+    }
+}
+
+fn parse_expr<'a>(input: Span) -> IResult<Span, Expr> {
+    branch::alt((parse_infix, parse_expr_nobin))(input)
+}
+
+fn parse_expr_nobin<'a>(input: Span) -> IResult<Span, Expr> {
+    branch::alt((parse_unary, parse_expr_nobin_noun))(input)
+}
+
+fn parse_expr_nobin_noun<'a>(input: Span) -> IResult<Span, Expr> {
+    parse_value(input)
+}
+
+fn parse_value(input: Span) -> IResult<Span, Expr> {
+    // More primitive type categories go here (branch::alt() if > 1):
+    parse_number(input)
+}
+
+fn parse_number(input: Span) -> IResult<Span, Expr> {
+    // More number types go here (branch::alt() if > 1):
+    parse_int(input)
+}
+
+fn parse_int(input: Span) -> IResult<Span, Expr> {
+    let (input, digits) = digit1(input)?;
+    let int = match digits.fragment.parse() {
+        Ok(int) => int,
+        Err(err) => {
+            return Err(Err::Failure(Error {
+                input,
+                val: Some(digits),
+                error: ErrorKind::ParseInt(err),
+            }))
+        }
+    };
+    Ok((
+        input,
+        Expr {
+            span: digits,
+            val: Value::Int(int),
+        },
+    ))
+}
+
+fn parse_unary(input: Span) -> IResult<Span, Expr> {
+    let (input, (span, func_map)) = tag_unary(input)?;
+    let (input, right) = parse_expr_nobin(input)?;
+    Ok((
+        input,
+        Expr {
+            span,
+            val: Value::UnFunc(func_map.func, Box::new(right)),
+        },
+    ))
+}
+
+fn parse_infix(input: Span) -> IResult<Span, Expr> {
+    // Initialize with minimum precedence 1.
+    parse_infix_first(input, 1)
+}
+fn parse_infix_first<'a>(input: Span, min_prec: u8) -> IResult<Span, Expr> {
+    // First, find left hand side expression. Search for everything but BinOps.
+    let (input, left) = parse_expr_nobin(input)?;
+    parse_infix_left(input, min_prec, left)
+}
+fn parse_infix_prec<'a>(input: Span, min_prec: u8) -> IResult<Span, Expr> {
+    // Almost identical to parse_infix_first(), but we do not accept unary ops.
+    let (input, left) = parse_expr_nobin_noun(input)?;
+    parse_infix_left(input, min_prec, left)
+}
+fn parse_infix_left<'a>(
+    input_bin: Span<'a>,
+    min_prec: u8,
+    left: Expr<'a>,
+) -> IResult<'a, Span<'a>, Expr<'a>> {
+    // See if we can find an infix function. If not, return what we have.
+    let (input, (span, func_map)) = match tag_infix(input_bin) {
+        Ok(res) => res,
+        Err(Err::Error(Error { input, .. })) => return Ok((input, left)),
+        Err(err) => return Err(err),
+    };
+
+    // Does the new infix fulfill our precedence criteria?
+    if func_map.prec < min_prec {
+        return Ok((input_bin, left));
+    }
+
+    // Parse the right-hand-side.
+    let new_min_prec = match func_map.ass {
+        Ass::Left => func_map.prec + 1,
+        Ass::Right => func_map.prec,
+    };
+    let (input, right) = parse_infix_prec(input, new_min_prec)?;
+
+    // Put together the infix function with arguments. Continue forward.
+    let expr = Expr {
+        span,
+        val: Value::Func(func_map.func, Box::new(left), Box::new(right)),
+    };
+    parse_infix_left(input, min_prec, expr)
+}
+
+fn tag_unary(input: Span) -> IResult<Span, SpanFuncmap> {
+    tag_func(input, &UNARYS)
+}
+
+fn tag_infix(input: Span) -> IResult<Span, SpanFuncmap> {
+    tag_func(input, &INFIXS)
+}
+
+fn tag_func<'a>(input: Span<'a>, funcs: &'a [Funcmap]) -> IResult<'a, Span<'a>, SpanFuncmap<'a>> {
+    for func_map in funcs.iter() {
+        match tag(func_map.keyword)(input) {
+            Ok((input, span)) => return Ok((input, (span, &func_map))),
+            Err(Err::Error(_)) => (),
+            Err(err) => return Err(err),
+        }
+    }
+    Err(Err::Error(Error {
+        input,
+        val: None,
+        error: ErrorKind::Nom(error::ErrorKind::Tag),
+    }))
+}
+
+#[derive(Debug)]
+enum SimpleExpr<'a> {
+    Int(&'a i32),
+    UnSub(Box<SimpleExpr<'a>>),
+    Pow(Box<SimpleExpr<'a>>, Box<SimpleExpr<'a>>),
+    Mult(Box<SimpleExpr<'a>>, Box<SimpleExpr<'a>>),
+    Div(Box<SimpleExpr<'a>>, Box<SimpleExpr<'a>>),
+    Add(Box<SimpleExpr<'a>>, Box<SimpleExpr<'a>>),
+    Sub(Box<SimpleExpr<'a>>, Box<SimpleExpr<'a>>),
+}
+
+impl<'a> SimpleExpr<'a> {
+    fn new(tree: &'a Expr) -> Self {
+        match tree {
+            Expr {
+                val: Value::Int(int),
+                ..
+            } => SimpleExpr::Int(&int),
+            Expr {
+                val: Value::UnFunc(Function::UnSub, x),
+                ..
+            } => SimpleExpr::UnSub(Box::new(SimpleExpr::new(x))),
+            Expr {
+                val: Value::Func(Function::Pow, x, y),
+                ..
+            } => SimpleExpr::Pow(Box::new(SimpleExpr::new(x)), Box::new(SimpleExpr::new(y))),
+            Expr {
+                val: Value::Func(Function::Mult, x, y),
+                ..
+            } => SimpleExpr::Mult(Box::new(SimpleExpr::new(x)), Box::new(SimpleExpr::new(y))),
+            Expr {
+                val: Value::Func(Function::Div, x, y),
+                ..
+            } => SimpleExpr::Div(Box::new(SimpleExpr::new(x)), Box::new(SimpleExpr::new(y))),
+            Expr {
+                val: Value::Func(Function::Add, x, y),
+                ..
+            } => SimpleExpr::Add(Box::new(SimpleExpr::new(x)), Box::new(SimpleExpr::new(y))),
+            Expr {
+                val: Value::Func(Function::Sub, x, y),
+                ..
+            } => SimpleExpr::Sub(Box::new(SimpleExpr::new(x)), Box::new(SimpleExpr::new(y))),
+            _ => panic!(),
+        }
+    }
+}
+
+impl<'a> error::ParseError<Span<'a>> for Error<'a> {
+    fn from_error_kind(input: Span<'a>, kind: error::ErrorKind) -> Self {
+        Error {
+            input,
+            val: None,
+            error: ErrorKind::Nom(kind),
+        }
+    }
+
+    fn append(_: Span<'a>, _: error::ErrorKind, other: Self) -> Self {
+        other
+    }
+}
+
+struct Error<'a> {
+    input: Span<'a>,
+    val: Option<Span<'a>>,
+    error: ErrorKind,
+}
+
+enum ErrorKind {
+    NotRecognised,
+    Incomplete,
+    ParseInt(std::num::ParseIntError),
+    Nom(error::ErrorKind),
+}
+
+impl ErrorKind {
+    fn description(&self) -> String {
+        match self {
+            ErrorKind::NotRecognised => String::from("Failed to parse input."),
+            ErrorKind::Incomplete => String::from("There was not enough data."),
+            ErrorKind::ParseInt(err) => format!("Parse Int Error ({})", &err),
+            ErrorKind::Nom(err) => String::from(err.description()),
+        }
+    }
+}