mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-09-10 11:36:42 +00:00
Add tracing to custom parsers (#469)
This commit is contained in:
parent
94eec34bdb
commit
ef98c1e0ba
1 changed files with 343 additions and 291 deletions
|
@ -396,6 +396,8 @@ pub fn parse_module_checked<'input>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<ast::Module<'input>> {
|
fn module<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<ast::Module<'input>> {
|
||||||
|
trace(
|
||||||
|
"module",
|
||||||
(
|
(
|
||||||
version,
|
version,
|
||||||
target,
|
target,
|
||||||
|
@ -406,7 +408,8 @@ fn module<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<ast::Module
|
||||||
.map(|(version, _, _, directives, _)| ast::Module {
|
.map(|(version, _, _, directives, _)| ast::Module {
|
||||||
version,
|
version,
|
||||||
directives,
|
directives,
|
||||||
})
|
}),
|
||||||
|
)
|
||||||
.parse_next(stream)
|
.parse_next(stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,6 +443,8 @@ fn shader_model<'a>(stream: &mut &str) -> PResult<(u32, Option<char>)> {
|
||||||
fn directive<'a, 'input>(
|
fn directive<'a, 'input>(
|
||||||
stream: &mut PtxParser<'a, 'input>,
|
stream: &mut PtxParser<'a, 'input>,
|
||||||
) -> PResult<Option<ast::Directive<'input, ast::ParsedOperand<&'input str>>>> {
|
) -> PResult<Option<ast::Directive<'input, ast::ParsedOperand<&'input str>>>> {
|
||||||
|
trace(
|
||||||
|
"directive",
|
||||||
with_recovery(
|
with_recovery(
|
||||||
alt((
|
alt((
|
||||||
// When adding a new variant here remember to add its first token into recovery parser down below
|
// When adding a new variant here remember to add its first token into recovery parser down below
|
||||||
|
@ -466,7 +471,8 @@ fn directive<'a, 'input>(
|
||||||
.map(|(_, x)| x),
|
.map(|(_, x)| x),
|
||||||
|text| PtxError::UnrecognizedDirective(text.unwrap_or("")),
|
|text| PtxError::UnrecognizedDirective(text.unwrap_or("")),
|
||||||
)
|
)
|
||||||
.map(Option::flatten)
|
.map(Option::flatten),
|
||||||
|
)
|
||||||
.parse_next(stream)
|
.parse_next(stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,17 +489,22 @@ fn module_variable<'a, 'input>(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
|
fn file<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
|
||||||
|
trace(
|
||||||
|
"file",
|
||||||
(
|
(
|
||||||
Token::DotFile,
|
Token::DotFile,
|
||||||
u32,
|
u32,
|
||||||
Token::String,
|
Token::String,
|
||||||
opt((Token::Comma, u32, Token::Comma, u32)),
|
opt((Token::Comma, u32, Token::Comma, u32)),
|
||||||
)
|
)
|
||||||
.void()
|
.void(),
|
||||||
|
)
|
||||||
.parse_next(stream)
|
.parse_next(stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn section<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
|
fn section<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
|
||||||
|
trace(
|
||||||
|
"section",
|
||||||
(
|
(
|
||||||
Token::DotSection.void(),
|
Token::DotSection.void(),
|
||||||
dot_ident.void(),
|
dot_ident.void(),
|
||||||
|
@ -501,7 +512,8 @@ fn section<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
|
||||||
repeat::<_, _, (), _, _>(0.., section_dwarf_line),
|
repeat::<_, _, (), _, _>(0.., section_dwarf_line),
|
||||||
Token::RBrace.void(),
|
Token::RBrace.void(),
|
||||||
)
|
)
|
||||||
.void()
|
.void(),
|
||||||
|
)
|
||||||
.parse_next(stream)
|
.parse_next(stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +547,9 @@ fn function<'a, 'input>(
|
||||||
ast::LinkingDirective,
|
ast::LinkingDirective,
|
||||||
ast::Function<'input, &'input str, ast::Statement<ParsedOperand<&'input str>>>,
|
ast::Function<'input, &'input str, ast::Statement<ParsedOperand<&'input str>>>,
|
||||||
)> {
|
)> {
|
||||||
let (linking, function) = (
|
let (linking, function) = trace(
|
||||||
|
"function",
|
||||||
|
(
|
||||||
linking_directives,
|
linking_directives,
|
||||||
method_declaration,
|
method_declaration,
|
||||||
repeat(0.., tuning_directive),
|
repeat(0.., tuning_directive),
|
||||||
|
@ -550,7 +564,8 @@ fn function<'a, 'input>(
|
||||||
body,
|
body,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
|
)
|
||||||
.parse_next(stream)?;
|
.parse_next(stream)?;
|
||||||
stream.state.record_function(&function.func_directive);
|
stream.state.record_function(&function.func_directive);
|
||||||
Ok((linking, function))
|
Ok((linking, function))
|
||||||
|
@ -559,6 +574,8 @@ fn function<'a, 'input>(
|
||||||
fn linking_directives<'a, 'input>(
|
fn linking_directives<'a, 'input>(
|
||||||
stream: &mut PtxParser<'a, 'input>,
|
stream: &mut PtxParser<'a, 'input>,
|
||||||
) -> PResult<ast::LinkingDirective> {
|
) -> PResult<ast::LinkingDirective> {
|
||||||
|
trace(
|
||||||
|
"linking_directives",
|
||||||
repeat(
|
repeat(
|
||||||
0..,
|
0..,
|
||||||
dispatch! { any;
|
dispatch! { any;
|
||||||
|
@ -568,7 +585,8 @@ fn linking_directives<'a, 'input>(
|
||||||
_ => fail
|
_ => fail
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.fold(|| ast::LinkingDirective::NONE, |x, y| x | y)
|
.fold(|| ast::LinkingDirective::NONE, |x, y| x | y),
|
||||||
|
)
|
||||||
.parse_next(stream)
|
.parse_next(stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,11 +698,11 @@ fn tuple1to3_u32<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<(u32
|
||||||
fn function_body<'a, 'input>(
|
fn function_body<'a, 'input>(
|
||||||
stream: &mut PtxParser<'a, 'input>,
|
stream: &mut PtxParser<'a, 'input>,
|
||||||
) -> PResult<Option<Vec<ast::Statement<ParsedOperandStr<'input>>>>> {
|
) -> PResult<Option<Vec<ast::Statement<ParsedOperandStr<'input>>>>> {
|
||||||
dispatch! {any;
|
trace("function_body", dispatch! {any;
|
||||||
(Token::LBrace, _) => terminated(repeat_without_none(statement), Token::RBrace).map(Some),
|
(Token::LBrace, _) => terminated(repeat_without_none(statement), Token::RBrace).map(Some),
|
||||||
(Token::Semicolon, _) => empty.map(|_| None),
|
(Token::Semicolon, _) => empty.map(|_| None),
|
||||||
_ => fail
|
_ => fail
|
||||||
}
|
})
|
||||||
.parse_next(stream)
|
.parse_next(stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,7 +763,7 @@ fn take_till_inclusive<I: Stream, E: ParserError<I>>(
|
||||||
}
|
}
|
||||||
Err(ParserError::from_error_kind(input, ErrorKind::Eof))
|
Err(ParserError::from_error_kind(input, ErrorKind::Eof))
|
||||||
}
|
}
|
||||||
move |stream: &mut I| {
|
trace("take_till_inclusive", move |stream: &mut I| {
|
||||||
let mut should_backtrack = false;
|
let mut should_backtrack = false;
|
||||||
let offset = get_offset(stream, &backtrack_token, &end_token, &mut should_backtrack)?;
|
let offset = get_offset(stream, &backtrack_token, &end_token, &mut should_backtrack)?;
|
||||||
let result = stream.next_slice(offset);
|
let result = stream.next_slice(offset);
|
||||||
|
@ -757,7 +775,7 @@ fn take_till_inclusive<I: Stream, E: ParserError<I>>(
|
||||||
} else {
|
} else {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -783,6 +801,8 @@ fn with_recovery<'a, 'input: 'a, T>(
|
||||||
mut recovery: impl Parser<PtxParser<'a, 'input>, &'a [(Token<'input>, logos::Span)], ContextError>,
|
mut recovery: impl Parser<PtxParser<'a, 'input>, &'a [(Token<'input>, logos::Span)], ContextError>,
|
||||||
mut error: impl FnMut(Option<&'input str>) -> PtxError<'input>,
|
mut error: impl FnMut(Option<&'input str>) -> PtxError<'input>,
|
||||||
) -> impl Parser<PtxParser<'a, 'input>, Option<T>, ContextError> {
|
) -> impl Parser<PtxParser<'a, 'input>, Option<T>, ContextError> {
|
||||||
|
trace(
|
||||||
|
"with_recovery",
|
||||||
move |stream: &mut PtxParser<'a, 'input>| {
|
move |stream: &mut PtxParser<'a, 'input>| {
|
||||||
let input_start = stream.input.first().map(|(_, s)| s).cloned();
|
let input_start = stream.input.first().map(|(_, s)| s).cloned();
|
||||||
let stream_start = stream.checkpoint();
|
let stream_start = stream.checkpoint();
|
||||||
|
@ -803,7 +823,8 @@ fn with_recovery<'a, 'input: 'a, T>(
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pragma<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
|
fn pragma<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
|
||||||
|
@ -815,6 +836,8 @@ fn pragma<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> {
|
||||||
fn method_parameter<'a, 'input: 'a>(
|
fn method_parameter<'a, 'input: 'a>(
|
||||||
state_space: StateSpace,
|
state_space: StateSpace,
|
||||||
) -> impl Parser<PtxParser<'a, 'input>, Variable<&'input str>, ContextError> {
|
) -> impl Parser<PtxParser<'a, 'input>, Variable<&'input str>, ContextError> {
|
||||||
|
trace(
|
||||||
|
"method_parameter",
|
||||||
move |stream: &mut PtxParser<'a, 'input>| {
|
move |stream: &mut PtxParser<'a, 'input>| {
|
||||||
let (align, vector, type_, name) = variable_declaration.parse_next(stream)?;
|
let (align, vector, type_, name) = variable_declaration.parse_next(stream)?;
|
||||||
let array_dimensions = if state_space != StateSpace::Reg {
|
let array_dimensions = if state_space != StateSpace::Reg {
|
||||||
|
@ -835,18 +858,22 @@ fn method_parameter<'a, 'input: 'a>(
|
||||||
name,
|
name,
|
||||||
array_init: Vec::new(),
|
array_init: Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: split to a separate type
|
// TODO: split to a separate type
|
||||||
fn variable_declaration<'a, 'input>(
|
fn variable_declaration<'a, 'input>(
|
||||||
stream: &mut PtxParser<'a, 'input>,
|
stream: &mut PtxParser<'a, 'input>,
|
||||||
) -> PResult<(Option<u32>, Option<NonZeroU8>, ScalarType, &'input str)> {
|
) -> PResult<(Option<u32>, Option<NonZeroU8>, ScalarType, &'input str)> {
|
||||||
|
trace(
|
||||||
|
"variable_declaration",
|
||||||
(
|
(
|
||||||
opt(align.verify(|x| x.count_ones() == 1)),
|
opt(align.verify(|x| x.count_ones() == 1)),
|
||||||
vector_prefix,
|
vector_prefix,
|
||||||
scalar_type,
|
scalar_type,
|
||||||
ident,
|
ident,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.parse_next(stream)
|
.parse_next(stream)
|
||||||
}
|
}
|
||||||
|
@ -855,6 +882,8 @@ fn multi_variable<'a, 'input: 'a>(
|
||||||
extern_: bool,
|
extern_: bool,
|
||||||
state_space: StateSpace,
|
state_space: StateSpace,
|
||||||
) -> impl Parser<PtxParser<'a, 'input>, MultiVariable<&'input str>, ContextError> {
|
) -> impl Parser<PtxParser<'a, 'input>, MultiVariable<&'input str>, ContextError> {
|
||||||
|
trace(
|
||||||
|
"multi_variable",
|
||||||
move |stream: &mut PtxParser<'a, 'input>| {
|
move |stream: &mut PtxParser<'a, 'input>| {
|
||||||
let ((align, vector, type_, name), count) = (
|
let ((align, vector, type_, name), count) = (
|
||||||
variable_declaration,
|
variable_declaration,
|
||||||
|
@ -903,14 +932,17 @@ fn multi_variable<'a, 'input: 'a>(
|
||||||
},
|
},
|
||||||
count,
|
count,
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn array_initializer<'a, 'input: 'a>(
|
fn array_initializer<'b, 'a: 'b, 'input: 'a>(
|
||||||
vector: Option<NonZeroU8>,
|
vector: Option<NonZeroU8>,
|
||||||
type_: ScalarType,
|
type_: ScalarType,
|
||||||
array_dimensions: &mut Vec<u32>,
|
array_dimensions: &'b mut Vec<u32>,
|
||||||
) -> impl Parser<PtxParser<'a, 'input>, Vec<u8>, ContextError> + '_ {
|
) -> impl Parser<PtxParser<'a, 'input>, Vec<u8>, ContextError> + 'b {
|
||||||
|
trace(
|
||||||
|
"array_initializer",
|
||||||
move |stream: &mut PtxParser<'a, 'input>| {
|
move |stream: &mut PtxParser<'a, 'input>| {
|
||||||
Token::Eq.parse_next(stream)?;
|
Token::Eq.parse_next(stream)?;
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
|
@ -932,13 +964,16 @@ fn array_initializer<'a, 'input: 'a>(
|
||||||
let result_size = type_.size_of() as usize * array_dimensions[0] as usize;
|
let result_size = type_.size_of() as usize * array_dimensions[0] as usize;
|
||||||
result.extend(iter::repeat(0u8).take(result_size - result.len()));
|
result.extend(iter::repeat(0u8).take(result_size - result.len()));
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value_initializer<'a, 'input: 'a>(
|
fn value_initializer<'a, 'input: 'a>(
|
||||||
vector: Option<NonZeroU8>,
|
vector: Option<NonZeroU8>,
|
||||||
type_: ScalarType,
|
type_: ScalarType,
|
||||||
) -> impl Parser<PtxParser<'a, 'input>, Vec<u8>, ContextError> {
|
) -> impl Parser<PtxParser<'a, 'input>, Vec<u8>, ContextError> {
|
||||||
|
trace(
|
||||||
|
"value_initializer",
|
||||||
move |stream: &mut PtxParser<'a, 'input>| {
|
move |stream: &mut PtxParser<'a, 'input>| {
|
||||||
Token::Eq.parse_next(stream)?;
|
Token::Eq.parse_next(stream)?;
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
|
@ -948,13 +983,16 @@ fn value_initializer<'a, 'input: 'a>(
|
||||||
}
|
}
|
||||||
single_value_append(&mut result, type_).parse_next(stream)?;
|
single_value_append(&mut result, type_).parse_next(stream)?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn single_value_append<'a, 'input: 'a>(
|
fn single_value_append<'b, 'a: 'b, 'input: 'a>(
|
||||||
accumulator: &mut Vec<u8>,
|
accumulator: &'b mut Vec<u8>,
|
||||||
type_: ScalarType,
|
type_: ScalarType,
|
||||||
) -> impl Parser<PtxParser<'a, 'input>, (), ContextError> + '_ {
|
) -> impl Parser<PtxParser<'a, 'input>, (), ContextError> + 'b {
|
||||||
|
trace(
|
||||||
|
"single_value_append",
|
||||||
move |stream: &mut PtxParser<'a, 'input>| {
|
move |stream: &mut PtxParser<'a, 'input>| {
|
||||||
let value = immediate_value.parse_next(stream)?;
|
let value = immediate_value.parse_next(stream)?;
|
||||||
match (type_, value) {
|
match (type_, value) {
|
||||||
|
@ -1015,7 +1053,8 @@ fn single_value_append<'a, 'input: 'a>(
|
||||||
_ => return Err(ErrMode::from_error_kind(stream, ErrorKind::Verify)),
|
_ => return Err(ErrMode::from_error_kind(stream, ErrorKind::Verify)),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn array_dimensions<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<Vec<u32>> {
|
fn array_dimensions<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<Vec<u32>> {
|
||||||
|
@ -1188,20 +1227,26 @@ fn debug_directive<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()
|
||||||
fn block_statement<'a, 'input>(
|
fn block_statement<'a, 'input>(
|
||||||
stream: &mut PtxParser<'a, 'input>,
|
stream: &mut PtxParser<'a, 'input>,
|
||||||
) -> PResult<ast::Statement<ParsedOperandStr<'input>>> {
|
) -> PResult<ast::Statement<ParsedOperandStr<'input>>> {
|
||||||
|
trace(
|
||||||
|
"block_statement",
|
||||||
delimited(Token::LBrace, repeat_without_none(statement), Token::RBrace)
|
delimited(Token::LBrace, repeat_without_none(statement), Token::RBrace)
|
||||||
.map(|s| ast::Statement::Block(s))
|
.map(|s| ast::Statement::Block(s)),
|
||||||
|
)
|
||||||
.parse_next(stream)
|
.parse_next(stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn repeat_without_none<Input: Stream, Output, Error: ParserError<Input>>(
|
fn repeat_without_none<Input: Stream, Output, Error: ParserError<Input>>(
|
||||||
parser: impl Parser<Input, Option<Output>, Error>,
|
parser: impl Parser<Input, Option<Output>, Error>,
|
||||||
) -> impl Parser<Input, Vec<Output>, Error> {
|
) -> impl Parser<Input, Vec<Output>, Error> {
|
||||||
|
trace(
|
||||||
|
"repeat_without_none",
|
||||||
repeat(0.., parser).fold(Vec::new, |mut acc: Vec<_>, item| {
|
repeat(0.., parser).fold(Vec::new, |mut acc: Vec<_>, item| {
|
||||||
if let Some(item) = item {
|
if let Some(item) = item {
|
||||||
acc.push(item);
|
acc.push(item);
|
||||||
}
|
}
|
||||||
acc
|
acc
|
||||||
})
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ident_literal<
|
fn ident_literal<
|
||||||
|
@ -1267,11 +1312,14 @@ impl<Ident> ast::ParsedOperand<Ident> {
|
||||||
}
|
}
|
||||||
.parse_next(stream)
|
.parse_next(stream)
|
||||||
}
|
}
|
||||||
|
trace(
|
||||||
|
"operand",
|
||||||
alt((
|
alt((
|
||||||
ident_operands,
|
ident_operands,
|
||||||
immediate_value.map(ast::ParsedOperand::Imm),
|
immediate_value.map(ast::ParsedOperand::Imm),
|
||||||
vector_operand.map(ast::ParsedOperand::VecPack),
|
vector_operand.map(ast::ParsedOperand::VecPack),
|
||||||
))
|
)),
|
||||||
|
)
|
||||||
.parse_next(stream)
|
.parse_next(stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1445,7 +1493,9 @@ fn bra<'a, 'input>(
|
||||||
fn call<'a, 'input>(
|
fn call<'a, 'input>(
|
||||||
stream: &mut PtxParser<'a, 'input>,
|
stream: &mut PtxParser<'a, 'input>,
|
||||||
) -> PResult<ast::Instruction<ParsedOperandStr<'input>>> {
|
) -> PResult<ast::Instruction<ParsedOperandStr<'input>>> {
|
||||||
let (uni, return_arguments, name, input_arguments) = (
|
let (uni, return_arguments, name, input_arguments) = trace(
|
||||||
|
"call",
|
||||||
|
(
|
||||||
opt(Token::DotUni),
|
opt(Token::DotUni),
|
||||||
opt((
|
opt((
|
||||||
Token::LParen,
|
Token::LParen,
|
||||||
|
@ -1458,10 +1508,12 @@ fn call<'a, 'input>(
|
||||||
opt((
|
opt((
|
||||||
Token::Comma.void(),
|
Token::Comma.void(),
|
||||||
Token::LParen.void(),
|
Token::LParen.void(),
|
||||||
separated(1.., ParsedOperand::<&'input str>::parse, Token::Comma).map(|x: Vec<_>| x),
|
separated(1.., ParsedOperand::<&'input str>::parse, Token::Comma)
|
||||||
|
.map(|x: Vec<_>| x),
|
||||||
Token::RParen.void(),
|
Token::RParen.void(),
|
||||||
)
|
)
|
||||||
.map(|(_, _, arguments, _)| arguments)),
|
.map(|(_, _, arguments, _)| arguments)),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.parse_next(stream)?;
|
.parse_next(stream)?;
|
||||||
let uniform = uni.is_some();
|
let uniform = uni.is_some();
|
||||||
|
@ -1536,7 +1588,7 @@ where
|
||||||
ParseRequired: Parser<Input, RequiredOutput, Error>,
|
ParseRequired: Parser<Input, RequiredOutput, Error>,
|
||||||
Error: ParserError<Input>,
|
Error: ParserError<Input>,
|
||||||
{
|
{
|
||||||
move |input: &mut Input| -> Result<(Option<OptionalOutput>, RequiredOutput), ErrMode<Error>> {
|
trace("first_optional", move |input: &mut Input| -> Result<(Option<OptionalOutput>, RequiredOutput), ErrMode<Error>> {
|
||||||
let start = input.checkpoint();
|
let start = input.checkpoint();
|
||||||
|
|
||||||
let parsed_optional = match optional.parse_next(input) {
|
let parsed_optional = match optional.parse_next(input) {
|
||||||
|
@ -1555,7 +1607,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((None, required.parse_next(input)?))
|
Ok((None, required.parse_next(input)?))
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This macro is responsible for generating parser code for instruction parser.
|
// This macro is responsible for generating parser code for instruction parser.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue