trunk
Alona EM 2022-01-16 16:49:26 +00:00
commit 11133bc7de
3 changed files with 63 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
Cargo.lock

11
Cargo.toml Normal file
View File

@ -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"] }

50
src/lib.rs Normal file
View File

@ -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<T>(
tree: Result<T, ParseError<usize, Token, &str>>,
file_name: &str,
file_contents: &str,
) -> anyhow::Result<T> {
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");
}
}
}