From 7ba1586d6c6336c50b5b13809fec5f42f3f78a21 Mon Sep 17 00:00:00 2001 From: Andrzej Janik Date: Mon, 13 Dec 2021 17:20:06 +0100 Subject: Make all user errors recoverable --- ptx/src/ptx.lalrpop | 160 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 106 insertions(+), 54 deletions(-) (limited to 'ptx') diff --git a/ptx/src/ptx.lalrpop b/ptx/src/ptx.lalrpop index 5c4811c..181a727 100644 --- a/ptx/src/ptx.lalrpop +++ b/ptx/src/ptx.lalrpop @@ -271,61 +271,79 @@ NumToken: (&'input str, u32, bool) = { } F32Num: f32 = { - =>? { + => { match u32::from_str_radix(&s[2..], 16) { - Ok(x) => Ok(unsafe { std::mem::transmute::<_, f32>(x) }), - Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + Ok(x) => unsafe { std::mem::transmute::<_, f32>(x) }, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0.0 + } } } } F64Num: f64 = { - =>? { + => { match u64::from_str_radix(&s[2..], 16) { - Ok(x) => Ok(unsafe { std::mem::transmute::<_, f64>(x) }), - Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + Ok(x) => unsafe { std::mem::transmute::<_, f64>(x) }, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0.0 + } } } } U8Num: u8 = { - =>? { + => { let (text, radix, _) = x; match u8::from_str_radix(text, radix) { - Ok(x) => Ok(x), - Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + Ok(x) => x, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + } } } } U16Num: u16 = { - =>? { + => { let (text, radix, _) = x; match u16::from_str_radix(text, radix) { - Ok(x) => Ok(x), - Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + Ok(x) => x, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + } } } } U32Num: u32 = { - =>? { + => { let (text, radix, _) = x; match u32::from_str_radix(text, radix) { - Ok(x) => Ok(x), - Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + Ok(x) => x, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + } } } } // TODO: handle negative number properly S32Num: i32 = { - =>? { + => { let (text, radix, _) = x; match i32::from_str_radix(text, radix) { - Ok(x) => Ok(if sign.is_some() { -x } else { x }), - Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + Ok(x) => if sign.is_some() { -x } else { x }, + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + } } } } @@ -337,11 +355,17 @@ pub Module: ast::Module<'input> = { }; Version: (u8, u8) = { - ".version" =>? { + ".version" => { let dot = v.find('.').unwrap(); - let major = v[..dot].parse::().map_err(|e| ParseError::from(ast::PtxError::from(e)))?; - let minor = v[dot+1..].parse::().map_err(|e| ParseError::from(ast::PtxError::from(e)))?; - Ok((major,minor)) + let major = v[..dot].parse::().unwrap_or_else(|err| { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + }); + let minor = v[dot+1..].parse::().unwrap_or_else(|err| { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + 0 + }); + (major,minor) } } @@ -580,7 +604,7 @@ LocalVariable: ast::Variable<&'input str> = { let state_space = ast::StateSpace::Local; ast::Variable { align, v_type, state_space, name, array_init: Vec::new() } }, - ".local" > =>? { + ".local" > => { let (align, t, name, arr_or_ptr) = var; let state_space = ast::StateSpace::Local; let (v_type, array_init) = match arr_or_ptr { @@ -588,10 +612,11 @@ LocalVariable: ast::Variable<&'input str> = { (ast::Type::Array(t, dimensions), init) } ast::ArrayOrPointer::Pointer => { - return Err(ParseError::User { error: ast::PtxError::ZeroDimensionArray }); + errors.push(ParseError::User { error: ast::PtxError::ZeroDimensionArray }); + (ast::Type::Array(t, Vec::new()), Vec::new()) } }; - Ok(ast::Variable { align, v_type, state_space, name, array_init }) + ast::Variable { align, v_type, state_space, name, array_init } } } @@ -608,7 +633,7 @@ SharedVariable: ast::Variable<&'input str> = { let v_type = ast::Type::Vector(t, v_len); ast::Variable { align, v_type, state_space, name, array_init: Vec::new() } }, - ".shared" > =>? { + ".shared" > => { let (align, t, name, arr_or_ptr) = var; let state_space = ast::StateSpace::Shared; let (v_type, array_init) = match arr_or_ptr { @@ -616,10 +641,11 @@ SharedVariable: ast::Variable<&'input str> = { (ast::Type::Array(t, dimensions), init) } ast::ArrayOrPointer::Pointer => { - return Err(ParseError::User { error: ast::PtxError::ZeroDimensionArray }); + errors.push(ParseError::User { error: ast::PtxError::ZeroDimensionArray }); + (ast::Type::Array(t, Vec::new()), Vec::new()) } }; - Ok(ast::Variable { align, v_type, state_space, name, array_init }) + ast::Variable { align, v_type, state_space, name, array_init } } } @@ -628,7 +654,7 @@ ModuleVariable: (ast::LinkingDirective, ast::Variable<&'input str>) = { let (align, v_type, name, array_init) = def; (linking, ast::Variable { align, v_type, state_space, name, array_init }) }, - > =>? { + > => { let (align, t, name, arr_or_ptr) = var; let (v_type, state_space, array_init) = match arr_or_ptr { ast::ArrayOrPointer::Array { dimensions, init } => { @@ -636,12 +662,12 @@ ModuleVariable: (ast::LinkingDirective, ast::Variable<&'input str>) = { } ast::ArrayOrPointer::Pointer => { if !linking.contains(ast::LinkingDirective::EXTERN) { - return Err(ParseError::User { error: ast::PtxError::NonExternPointer }); + errors.push(ParseError::User { error: ast::PtxError::NonExternPointer }); } (ast::Type::Array(t, Vec::new()), space, Vec::new()) } }; - Ok((linking, ast::Variable{ align, v_type, state_space, name, array_init })) + (linking, ast::Variable{ align, v_type, state_space, name, array_init }) } } @@ -673,13 +699,12 @@ ParamVariable: (Option, Vec, ast::Type, &'input str) = { } ParamDeclaration: (Option, ast::Type, &'input str) = { - =>? { + => { let (align, array_init, v_type, name) = var; if array_init.len() > 0 { - Err(ParseError::User { error: ast::PtxError::ArrayInitalizer }) - } else { - Ok((align, v_type, name)) + errors.push(ParseError::User { error: ast::PtxError::ArrayInitalizer }); } + (align, v_type, name) } } @@ -1873,25 +1898,34 @@ CallOperand: ast::Operand<&'input str> = { // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#constants ImmediateValue: ast::ImmediateValue = { // TODO: treat negation correctly - =>? { + => { let (num, radix, is_unsigned) = x; if neg.is_some() { match i64::from_str_radix(num, radix) { - Ok(x) => Ok(ast::ImmediateValue::S64(-x)), - Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + Ok(x) => ast::ImmediateValue::S64(-x), + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + ast::ImmediateValue::S64(0) + } } } else if is_unsigned { match u64::from_str_radix(num, radix) { - Ok(x) => Ok(ast::ImmediateValue::U64(x)), - Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + Ok(x) => ast::ImmediateValue::U64(x), + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + ast::ImmediateValue::U64(0) + } } } else { match i64::from_str_radix(num, radix) { - Ok(x) => Ok(ast::ImmediateValue::S64(x)), + Ok(x) => ast::ImmediateValue::S64(x), Err(_) => { match u64::from_str_radix(num, radix) { - Ok(x) => Ok(ast::ImmediateValue::U64(x)), - Err(err) => Err(ParseError::User { error: ast::PtxError::from(err) }) + Ok(x) => ast::ImmediateValue::U64(x), + Err(err) => { + errors.push(ParseError::User { error: ast::PtxError::from(err) }); + ast::ImmediateValue::U64(0) + } } } } @@ -1918,13 +1952,25 @@ Arg2: ast::Arg2> = { }; MemberOperand: (&'input str, u8) = { - "." =>? { - let suf_idx = vector_index(suf)?; - Ok((pref, suf_idx)) - }, - =>? { - let suf_idx = vector_index(&suf[1..])?; - Ok((pref, suf_idx)) + "." => { + let suf_idx = match vector_index(suf) { + Ok(x) => x, + Err(err) => { + errors.push(err); + 0 + } + }; + (pref, suf_idx) + }, + => { + let suf_idx = match vector_index(&suf[1..]) { + Ok(x) => x, + Err(err) => { + errors.push(err); + 0 + } + }; + (pref, suf_idx) } }; @@ -2055,16 +2101,22 @@ VariableVector: (Option, u8, T, &'input str) = { // empty dimensions [0] means it's a pointer VariableArrayOrPointer: (Option, T, &'input str, ast::ArrayOrPointer) = { - =>? { + => { let mut dims = dims; let array_init = match init { Some(init) => { - let init_vec = init.to_vec(typ, &mut dims)?; + let init_vec = match init.to_vec(typ, &mut dims) { + Err(error) => { + errors.push(ParseError::User { error }); + Vec::new() + } + Ok(x) => x + }; ast::ArrayOrPointer::Array { dimensions: dims, init: init_vec } } None => { if dims.len() > 1 && dims.contains(&0) { - return Err(ParseError::User { error: ast::PtxError::ZeroDimensionArray }) + errors.push(ParseError::User { error: ast::PtxError::ZeroDimensionArray }); } match &*dims { [0] => ast::ArrayOrPointer::Pointer, @@ -2072,7 +2124,7 @@ VariableArrayOrPointer: (Option, T, &'input str, ast::ArrayOrPointer) = } } }; - Ok((align, typ, name, array_init)) + (align, typ, name, array_init) } } -- cgit v1.2.3