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