diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 4d76cadf867df4dc36f55d9c3012bb91000d9304..cecc9e8c2cb32e1e507578d9fed23a5c7b6c55bb 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -4,11 +4,16 @@
     "version": "2.0.0",
     "tasks": [
         {
-            "type": "cargo",
-            "subcommand": "build",
+            "type": "shell",
+            "label": "cargo check --example main_span_expr",
+            "command": "cargo check --example main_span_expr",
             "problemMatcher": [
                 "$rustc"
-            ]
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
         }
     ]
 }
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index cb26762684ba80d49d43c5c785395782e77ec6c7..2e2899c867e521b006534f256466ce84c5ec7f0a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,5 +1,10 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
+[[package]]
+name = "bytecount"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "cfg-if"
 version = "0.1.9"
@@ -10,6 +15,7 @@ name = "first"
 version = "0.1.0"
 dependencies = [
  "nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom_locate 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -39,6 +45,16 @@ dependencies = [
  "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "nom_locate"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rustc_version"
 version = "0.2.3"
@@ -98,10 +114,12 @@ version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
+"checksum bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f861d9ce359f56dbcb6e0c2a1cb84e52ad732cadb57b806adeb3c7668caccbd8"
 "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
 "checksum lexical-core 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b0f90c979adde96d19eb10eb6431ba0c441e2f9e9bdff868b2f6f5114ff519"
 "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
 "checksum nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c618b63422da4401283884e6668d39f819a106ef51f5f59b81add00075da35ca"
+"checksum nom_locate 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f932834fd8e391fc7710e2ba17e8f9f8645d846b55aa63207e17e110a1e1ce35"
 "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
 "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
diff --git a/examples/main_locate.rs b/examples/main_locate.rs
index 3ee29998f7abc3846049f39ceef6ed33ced71876..fdf884f5f69839630a866bb39945faf626934d2f 100644
--- a/examples/main_locate.rs
+++ b/examples/main_locate.rs
@@ -26,12 +26,14 @@ pub enum Expr<'a> {
     BinOp(Span<'a>, Box<Expr<'a>>, Op, Box<Expr<'a>>),
 }
 
+// this is the definititon of IResult 
 // type IResult<I, O, E = u32> = Result<(I, O), Err<I, E>>;
 
 pub fn parse_i32(i: Span) -> IResult<Span, Expr> {
     map(digit1, |digit_str: Span| {
         Expr::Num(digit_str, digit_str.fragment.parse::<i32>().unwrap())
     })(i)
+    // below is just an exapmle on howto generate an Error explicitly
     // Err(Err::Error((i, ErrorKind::Alpha)))
 }
 
diff --git a/examples/main_span_expr.rs b/examples/main_span_expr.rs
new file mode 100644
index 0000000000000000000000000000000000000000..139857ace9b12f370846b990b90960aeb7fd755b
--- /dev/null
+++ b/examples/main_span_expr.rs
@@ -0,0 +1,104 @@
+extern crate nom;
+
+use nom::{
+    branch::alt,
+    bytes::complete::tag,
+    character::complete::{digit1, multispace0},
+    combinator::map,
+    sequence::{preceded, tuple},
+    IResult,
+};
+
+use nom_locate::LocatedSpan;
+
+type Span<'a> = LocatedSpan<&'a str>;
+
+#[derive(Debug, PartialEq)]
+pub enum Op {
+    Add,
+    Sub,
+}
+
+type SpanOp<'a> = (Span<'a>, Op);
+
+fn parse_op(i: Span) -> IResult<Span, SpanOp> {
+    alt((
+        map(tag("+"), |s| (s, Op::Add)),
+        map(tag("-"), |s| (s, Op::Sub)),
+    ))(i)
+}
+
+#[derive(Debug, PartialEq)]
+pub enum Expr<'a> {
+    Num(i32),
+    BinOp(Box<SpanExpr<'a>>, SpanOp<'a>, Box<SpanExpr<'a>>),
+}
+
+type SpanExpr<'a> = (Span<'a>, Expr<'a>);
+
+pub fn parse_i32(i: Span) -> IResult<Span, SpanExpr> {
+    map(digit1, |digit_str: Span| {
+        (
+            digit_str,
+            Expr::Num(digit_str.fragment.parse::<i32>().unwrap()),
+        )
+    })(i)
+}
+
+fn parse_expr(i: Span) -> IResult<Span, SpanExpr> {
+    alt((
+        map(
+            tuple((parse_i32, preceded(multispace0, parse_op), parse_expr_ms)),
+            |(l, op, r)| (i, Expr::BinOp(Box::new(l), op, Box::new(r))),
+        ),
+        parse_i32,
+    ))(i)
+}
+
+fn parse_expr_ms(i: Span) -> IResult<Span, SpanExpr> {
+    preceded(multispace0, parse_expr)(i)
+}
+
+// dumps a Span into a String
+fn dump_span(s: &Span) -> String {
+    format!(
+        "[line :{:?}, col:{:?}, {:?}]",
+        s.line,
+        s.get_column(),
+        s.fragment
+    )
+}
+
+// dumps a SpanExpr into a String
+fn dump_expr(se: &SpanExpr) -> String {
+    let (s, e) = se;
+    match e {
+        Expr::Num(_) => dump_span(s),
+        Expr::BinOp(l, (sop, _), r) => {
+            format!("<{} {} {}>", dump_expr(l), dump_span(sop), dump_expr(r))
+        }
+    }
+}
+
+fn main() {
+    let (_, (s, e)) = parse_expr_ms(Span::new("\n    1+2 - \n3")).unwrap();
+    println!(
+        "span for the whole,expression: {:?}, \nline: {:?}, \ncolumn: {:?}",
+        s,
+        s.line,
+        s.get_column()
+    );
+
+    println!("raw e: {:?}", &e);
+    println!("pretty e {}", dump_expr(&(s, e)));
+}
+
+//
+// In this example, we have a `parse_expr_ms` is the "top" level parser.
+// It consumes white spaces, allowing the location information to reflect the exact
+// positions in the input file.
+//
+// The dump_expr will create a pretty printing of the expression with spans for
+// each terminal. This will be useful for later for precise type error reporting.
+//
+// The exrtra field is not used, it can be used for metadata, such as filename.