commit 11133bc7de474e4f8c89249a4d98bafce40e4b0d Author: Nixon Enraght-Moony Date: Sun Jan 16 16:49:26 2022 +0000 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..fe78f9b --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "lalrpop_codespan" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.52" +codespan-reporting = "0.11.1" +lalrpop-util = { version = "0.19.6", features = ["lexer"] } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..c457ce2 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,50 @@ +use anyhow::bail; +use codespan_reporting::{ + diagnostic::{Diagnostic, Label}, + files::SimpleFiles, + term::{ + emit, + termcolor::{ColorChoice, StandardStream}, + }, +}; +use lalrpop_util::{lexer::Token, ParseError}; + +pub fn report_error( + tree: Result>, + file_name: &str, + file_contents: &str, +) -> anyhow::Result { + match tree { + Ok(x) => Ok(x), + Err(e) => { + let mut err_files = SimpleFiles::new(); + let err_writer = StandardStream::stderr(ColorChoice::Auto); + let err_config = codespan_reporting::term::Config::default(); + + let main_file_id = err_files.add(file_name, file_contents); + let emit_err = |d| emit(&mut err_writer.lock(), &err_config, &err_files, d); + + let err = match e { + ParseError::InvalidToken { location } => Diagnostic::error() + .with_message("Invalid token") + .with_labels(vec![Label::primary(main_file_id, location..location + 1)]), + ParseError::UnrecognizedEOF { location, expected } => Diagnostic::error() + .with_message("Unexpected end of file") + .with_labels(vec![Label::primary(main_file_id, location..location + 1)]) + .with_notes(expected.iter().map(|e| format!("Expected {}", e)).collect()), + ParseError::UnrecognizedToken { token, expected } => Diagnostic::error() + .with_message("Unrecognized token") + .with_labels(vec![Label::primary(main_file_id, token.0..token.2)]) + .with_notes(expected.iter().map(|e| format!("Expected {}", e)).collect()), + ParseError::ExtraToken { token } => Diagnostic::error() + .with_message("Extra token") + .with_labels(vec![Label::primary(main_file_id, token.0..token.2)]), + ParseError::User { error } => bail!("User parse error: {}", error), + }; + + emit_err(&err)?; + + bail!("Parse error"); + } + } +}