Init
commit
11133bc7de
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
|
@ -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"] }
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue