51 lines
2.1 KiB
Rust
51 lines
2.1 KiB
Rust
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");
|
|
}
|
|
}
|
|
}
|