diff options
-rw-r--r-- | ptx/src/ast.rs | 10 | ||||
-rw-r--r-- | ptx/src/lib.rs | 52 | ||||
-rw-r--r-- | ptx/src/ptx.lalrpop | 21 | ||||
-rw-r--r-- | zluda_dump/README.md | 4 | ||||
-rw-r--r-- | zluda_dump/src/trace.rs | 4 |
5 files changed, 60 insertions, 31 deletions
diff --git a/ptx/src/ast.rs b/ptx/src/ast.rs index a8309b0..d308479 100644 --- a/ptx/src/ast.rs +++ b/ptx/src/ast.rs @@ -31,6 +31,16 @@ pub enum PtxError { ArrayInitalizer, #[error("")] NonExternPointer, + #[error("{start}:{end}")] + UnrecognizedStatement { + start: usize, + end: usize, + }, + #[error("{start}:{end}")] + UnrecognizedDirective { + start: usize, + end: usize, + }, } // For some weird reson this is illegal: diff --git a/ptx/src/lib.rs b/ptx/src/lib.rs index db9fc23..1cb9630 100644 --- a/ptx/src/lib.rs +++ b/ptx/src/lib.rs @@ -31,6 +31,7 @@ mod translate; use std::fmt; pub use crate::ptx::ModuleParser; +use ast::PtxError; pub use lalrpop_util::lexer::Token; pub use lalrpop_util::ParseError; pub use rspirv::dr::Error as SpirvError; @@ -91,33 +92,50 @@ impl ModuleParserExt for ModuleParser { } } -pub struct DisplayParseError<'a, Loc, Tok, Err>(pub &'a str, pub &'a ParseError<Loc, Tok, Err>); +pub struct DisplayParseError<'a, Loc, Tok, Err>(&'a str, &'a ParseError<Loc, Tok, Err>); -impl<'a, Loc, Tok, Err> fmt::Display for DisplayParseError<'a, Loc, Tok, Err> +impl<'a, Loc: fmt::Display + Into<usize> + Copy, Tok, Err> DisplayParseError<'a, Loc, Tok, Err> { + // unsafe because there's no guarantee that the input str is the one that this error was created from + pub unsafe fn new(error: &'a ParseError<Loc, Tok, Err>, text: &'a str) -> Self { + Self(text, error) + } +} + +impl<'a, Loc, Tok> fmt::Display for DisplayParseError<'a, Loc, Tok, PtxError> where - Loc: fmt::Display + Into<usize> + Copy, + Loc: fmt::Display, Tok: fmt::Display, - Err: fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.1 { - ParseError::UnrecognizedToken { - token: (start, token, end), - .. - } => { - let full_instruction = - unsafe { self.0.get_unchecked((*start).into()..(*end).into()) }; - write!( - f, - "`{}` unrecognized token `{}` found at {}:{}", - full_instruction, token, start, end - ) - } - _ => self.fmt(f), + ParseError::User { + error: PtxError::UnrecognizedStatement { start, end }, + } => self.fmt_unrecognized(f, *start, *end, "statement"), + ParseError::User { + error: PtxError::UnrecognizedDirective { start, end }, + } => self.fmt_unrecognized(f, *start, *end, "directive"), + _ => self.1.fmt(f), } } } +impl<'a, Loc, Tok, Err> DisplayParseError<'a, Loc, Tok, Err> { + fn fmt_unrecognized( + &self, + f: &mut fmt::Formatter, + start: usize, + end: usize, + kind: &'static str, + ) -> fmt::Result { + let full_substring = unsafe { self.0.get_unchecked(start..end) }; + write!( + f, + "Unrecognized {} `{}` found at {}:{}", + kind, full_substring, start, end + ) + } +} + pub(crate) fn without_none<T>(x: Vec<Option<T>>) -> Vec<T> { x.into_iter().filter_map(|x| x).collect() } diff --git a/ptx/src/ptx.lalrpop b/ptx/src/ptx.lalrpop index f6fd9cd..e3a4022 100644 --- a/ptx/src/ptx.lalrpop +++ b/ptx/src/ptx.lalrpop @@ -394,9 +394,11 @@ Directive: Option<ast::Directive<'input, ast::ParsedArgParams<'input>>> = { let (linking, var) = v; Some(ast::Directive::Variable(linking, var)) }, - ! => { - let err = <>; - errors.push(err.error); + @L ! @R => { + let (start, _, end)= (<>); + errors.push(ParseError::User { error: + ast::PtxError::UnrecognizedDirective { start, end } + }); None } }; @@ -527,15 +529,10 @@ Statement: Option<ast::Statement<ast::ParsedArgParams<'input>>> = { PragmaStatement => None, "{" <s:Statement*> "}" => Some(ast::Statement::Block(without_none(s))), @L ! ";" @R => { - let (start, mut err, _, end) = (<>); - // TODO: report this error more generally, perhaps in user error? - err.error = match err.error { - ParseError::UnrecognizedToken { token: (_, token, _), expected } => { - ParseError::UnrecognizedToken { token: (start, token, end), expected } - } - e => e - }; - errors.push(err.error); + let (start, _, _, end) = (<>); + errors.push(ParseError::User { error: + ast::PtxError::UnrecognizedStatement { start, end } + }); None } }; diff --git a/zluda_dump/README.md b/zluda_dump/README.md index 52cecc8..1e7c03b 100644 --- a/zluda_dump/README.md +++ b/zluda_dump/README.md @@ -1 +1,3 @@ -sed 's/(.*//g' log.txt | sort | uniq > uniq.txt
\ No newline at end of file +grep -E '^cu.*' log.txt | sed 's/(.*//g' | sort | uniq > uniq_host.txt
+cat *.log | grep "^Unrecognized s" | grep -Eo '`([^`]*)`' | sed -E 's/^`([^[:space:]]*).*`/\1/' | sort | uniq > uniq_statements.txt
+cat *.log | grep "^Unrecognized d" | grep -Eo '`([^`]*)`' | sed -E 's/^`([^`]*)`/\1/' | sort | uniq > uniq_directives.txt
\ No newline at end of file diff --git a/zluda_dump/src/trace.rs b/zluda_dump/src/trace.rs index eac6bbd..2afc1c5 100644 --- a/zluda_dump/src/trace.rs +++ b/zluda_dump/src/trace.rs @@ -177,6 +177,7 @@ impl StateTracker { DumpWriter::get_file_name(module_index, version, submodule_index, "log"),
));
fn_logger.log_io_error(self.writer.save_module_error_log(
+ module_text,
module_index,
version,
submodule_index,
@@ -230,6 +231,7 @@ impl DumpWriter { fn save_module_error_log<'input>(
&self,
+ module_text: &str,
module_index: usize,
version: Option<usize>,
submodule_index: Option<usize>,
@@ -247,7 +249,7 @@ impl DumpWriter { ));
let mut file = File::create(log_file)?;
for error in errors {
- let pretty_print_error = DisplayParseError("", error);
+ let pretty_print_error = unsafe { DisplayParseError::new(error, module_text) };
writeln!(file, "{}", pretty_print_error)?;
}
Ok(())
|