diff options
Diffstat (limited to '')
| -rw-r--r-- | src/main.rs | 32 | 
1 files changed, 29 insertions, 3 deletions
diff --git a/src/main.rs b/src/main.rs index e60a893..0abcea8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +extern crate bytecount;  extern crate lalrpop_util;  #[macro_use]  extern crate nom; @@ -11,16 +12,41 @@ pub mod parser;  use std::io::{self, Read}; +fn print_error(message: &str, source: &str, start: usize, end: usize) { +    let line_number = bytecount::count(source[..start].as_bytes(), '\n' as u8); +    let line_start = source[..start].rfind('\n').map(|i| i + 1).unwrap_or(0); +    let line_end = source[end..].find('\n').unwrap_or(0) + end; +    let context = &source[line_start..line_end]; + +    println!("error: {}", message); +    println!("  --> (stdin):{}:0", line_number); +    let line_number_str = line_number.to_string(); +    let line_number_width = line_number_str.len(); +    println!("{:w$} |", "", w = line_number_width); +    println!("{} | {}", line_number_str, context); +    println!("{:w$} | {:so$}{:^>ew$}", "", "", "", +             w = line_number_width, +             so = source[line_start..start].chars().count(), +             ew = ::std::cmp::max(1, source[start..end].chars().count())); +} +  fn main() {      let mut buffer = String::new();      io::stdin().read_to_string(&mut buffer).unwrap();      match parser::parse_expr(&buffer) {          Ok(e) => println!("{:?}", e),          Err(lalrpop_util::ParseError::User { error: lexer::LexicalError::Error(pos, e) }) => { -            let context = &buffer[pos..::std::cmp::min(buffer.len(), pos + 20)]; -            println!("Unexpected token in {:?}: {:?}...", e, context); +            print_error(&format!("Unexpected token {:?}", e), &buffer, pos, pos); +        } +        Err(lalrpop_util::ParseError::UnrecognizedToken { token: Some((start, t, end)), expected: e }) => { +            print_error(&format!("Unrecognized token {:?}", t), &buffer, start, end); +            if e.len() > 0 { +                println!("Expected {:?}", e); +            } +        } +        Err(e) => { +            print_error(&format!("Parser error {:?}", e), &buffer, 0, 0);          } -        Err(e) => println!("{:?}", e),      }      /*  | 
