Small fixes to ptx parsing

This commit is contained in:
Andrzej Janik 2025-08-30 02:56:53 +00:00
commit ab7592d70d

View file

@ -182,26 +182,29 @@ fn dot_ident<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<&'input
}
fn num<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<(&'input str, u32, bool)> {
any.verify_map(|(t, _)| {
Some(match t {
Token::Hex(s) => {
if s.ends_with('U') {
(&s[2..s.len() - 1], 16, true)
} else {
(&s[2..], 16, false)
trace(
"num",
any.verify_map(|(t, _)| {
Some(match t {
Token::Hex(s) => {
if s.ends_with('U') {
(&s[2..s.len() - 1], 16, true)
} else {
(&s[2..], 16, false)
}
}
}
Token::Decimal(s) => {
let radix = if s.starts_with('0') { 8 } else { 10 };
if s.ends_with('U') {
(&s[..s.len() - 1], radix, true)
} else {
(s, radix, false)
Token::Decimal(s) => {
let radix = if s.starts_with('0') { 8 } else { 10 };
if s.ends_with('U') {
(&s[..s.len() - 1], radix, true)
} else {
(s, radix, false)
}
}
}
_ => return None,
})
})
_ => return None,
})
}),
)
.parse_next(stream)
}
@ -290,13 +293,16 @@ fn u8<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<u8> {
}
fn u32<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<u32> {
take_error(num.map(|x| {
let (text, radix, _) = x;
match u32::from_str_radix(text, radix) {
Ok(x) => Ok(x),
Err(err) => Err((0, PtxError::from(err))),
}
}))
trace(
"u32",
take_error(num.map(|x| {
let (text, radix, _) = x;
match u32::from_str_radix(text, radix) {
Ok(x) => Ok(x),
Err(err) => Err((0, PtxError::from(err))),
}
})),
)
.parse_next(stream)
}
@ -547,7 +553,9 @@ fn any_bit_type<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
}
fn section_label<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
alt((ident, dot_ident)).void().parse_next(stream)
trace("section_label", alt((ident, dot_ident)))
.void()
.parse_next(stream)
}
fn function<'a, 'input>(
@ -654,13 +662,13 @@ fn kernel_arguments<'a, 'input>(
fn kernel_input<'a, 'input>(
stream: &mut PtxParser<'a, 'input>,
) -> PResult<ast::Variable<&'input str>> {
preceded(Token::DotParam, method_parameter(StateSpace::Param)).parse_next(stream)
preceded(Token::DotParam, method_parameter(StateSpace::Param, true)).parse_next(stream)
}
fn fn_input<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<ast::Variable<&'input str>> {
dispatch! { any;
(Token::DotParam, _) => method_parameter(StateSpace::Param),
(Token::DotReg, _) => method_parameter(StateSpace::Reg),
(Token::DotParam, _) => method_parameter(StateSpace::Param, false),
(Token::DotReg, _) => method_parameter(StateSpace::Reg, false),
_ => fail
}
.parse_next(stream)
@ -820,11 +828,30 @@ fn pragma<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
fn method_parameter<'a, 'input: 'a>(
state_space: StateSpace,
kernel_decl_rules: bool,
) -> impl Parser<PtxParser<'a, 'input>, Variable<&'input str>, ContextError> {
fn nvptx_kernel_declaration<'a, 'input>(
stream: &mut PtxParser<'a, 'input>,
) -> PResult<(Option<u32>, Option<NonZeroU8>, ScalarType, &'input str)> {
trace(
"nvptx_kernel_declaration",
(
vector_prefix,
scalar_type,
opt((Token::DotPtr, Token::DotGlobal)),
opt(align.verify(|x| x.count_ones() == 1)),
ident,
),
)
.map(|(vector, type_, _, align, name)| (align, vector, type_, name))
.parse_next(stream)
}
trace(
"method_parameter",
move |stream: &mut PtxParser<'a, 'input>| {
let (align, vector, type_, name) = variable_declaration.parse_next(stream)?;
if kernel_decl_rules {}
let (align, vector, type_, name) =
alt((variable_declaration, nvptx_kernel_declaration)).parse_next(stream)?;
let array_dimensions = if state_space != StateSpace::Reg {
opt(array_dimensions).parse_next(stream)?
} else {
@ -1751,10 +1778,12 @@ derive_parser!(
DotTarget,
#[token(".address_size")]
DotAddressSize,
#[token(".action")]
#[token(".section")]
DotSection,
#[token(".file")]
DotFile
DotFile,
#[token(".ptr")]
DotPtr
}
#[derive(Copy, Clone, Display, PartialEq, Eq, Hash)]
@ -3775,6 +3804,7 @@ derive_parser!(
mod tests {
use crate::first_optional;
use crate::parse_module_checked;
use crate::section;
use crate::PtxError;
use super::target;
@ -3997,4 +4027,77 @@ mod tests {
PtxError::UnrecognizedDirective(".global .bad_type foo;")
));
}
#[test]
fn dwarf_line() {
let text = "
.section .debug_abbrev
{
.b8 1 // Abbreviation Code
.b8 17 // DW_TAG_compile_unit
.b8 1 // DW_CHILDREN_yes
.b8 37 // DW_AT_producer
.b8 8 // DW_FORM_string
.b8 19 // DW_AT_language
.b8 5 // DW_FORM_data2
.b8 3 // DW_AT_name
.b8 8 // DW_FORM_string
.b8 16 // DW_AT_stmt_list
.b8 6 // DW_FORM_data4
.b8 27 // DW_AT_comp_dir
.b8 8 // DW_FORM_string
.b8 0 // EOM(1)
.b8 0 // EOM(2)
.b8 2 // Abbreviation Code
.b8 46 // DW_TAG_subprogram
.b8 0 // DW_CHILDREN_no
.b8 3 // DW_AT_name
.b8 8 // DW_FORM_string
.b8 32 // DW_AT_inline
.b8 11 // DW_FORM_data1
.b8 0 // EOM(1)
.b8 0 // EOM(2)
.b8 3 // Abbreviation Code
.b8 46 // DW_TAG_subprogram
.b8 1 // DW_CHILDREN_yes
.b8 17 // DW_AT_low_pc
.b8 1 // DW_FORM_addr
.b8 18 // DW_AT_high_pc
.b8 1 // DW_FORM_addr
.b8 49 // DW_AT_abstract_origin
.b8 19 // DW_FORM_ref4
.b8 0 // EOM(1)
.b8 0 // EOM(2)
.b8 4 // Abbreviation Code
.b8 29 // DW_TAG_inlined_subroutine
.b8 0 // DW_CHILDREN_no
.b8 49 // DW_AT_abstract_origin
.b8 19 // DW_FORM_ref4
.b8 17 // DW_AT_low_pc
.b8 1 // DW_FORM_addr
.b8 18 // DW_AT_high_pc
.b8 1 // DW_FORM_addr
.b8 88 // DW_AT_call_file
.b8 11 // DW_FORM_data1
.b8 89 // DW_AT_call_line
.b8 11 // DW_FORM_data1
.b8 87 // DW_AT_call_column
.b8 11 // DW_FORM_data1
.b8 0 // EOM(1)
.b8 0 // EOM(2)
.b8 0 // EOM(3)
}
";
let tokens = Token::lexer(text)
.map(|t| t.map(|t| (t, Span::default())))
.collect::<Result<Vec<_>, _>>()
.unwrap();
let mut errors = Vec::new();
let stream = super::PtxParser {
input: &tokens[..],
state: PtxParserState::new(text, &mut errors),
};
assert!(section.parse(stream).is_ok());
assert_eq!(errors.len(), 0);
}
}