From 3d9dfaeadf85c31295b2b14ac25bd66ddc774177 Mon Sep 17 00:00:00 2001 From: NanoTech Date: Tue, 6 Dec 2016 21:22:01 -0600 Subject: rustc-style error messages --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/main.rs | 32 +++++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 50a3b6b..9cc468a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,7 @@ name = "dhall" version = "0.1.0" dependencies = [ + "bytecount 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lalrpop 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "lalrpop-util 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)", "nom 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -43,6 +44,11 @@ name = "bitflags" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bytecount" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "diff" version = "0.1.9" @@ -246,6 +252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bit-set 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84527c7b0452f22545cc010e72d366a435561d2b28b978035550b3778c4d428d" "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d" "checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" +"checksum bytecount 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49e3c21915578e2300b08d3c174a8ac887e0c6421dff86fdc4d741dc29e5d413" "checksum diff 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e48977eec6d3b7707462c2dc2e1363ad91b5dd822cf942537ccdc2085dc87587" "checksum docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7ef30445607f6fc8720f0a0a2c7442284b629cf0d049286860fae23e71c4d9" "checksum fixedbitset 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3c33fc4c00db33f5174eb98aea809c4c007db0b71351d810a7e094ea3b64d" diff --git a/Cargo.toml b/Cargo.toml index 625cda1..8a5ad81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,5 +8,6 @@ build = "build.rs" lalrpop = "0.12.4" [dependencies] +bytecount = "0.1.4" lalrpop-util = "0.12.4" nom = "2.0.0" 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), } /* -- cgit v1.2.3