-
Notifications
You must be signed in to change notification settings - Fork 97
Open
Description
I'm in a similar situation to #199:
many1(block_expr_node).parse("*hi*")
fn block_expr_node<Input>() -> FnOpaque<Input, BlockExprNode>
where
Input: Stream<Token = char>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
opaque!(no_partial(
choice!(bold(), char()).message("while parsing block_expr_node")
))
}
fn char<Input>() -> impl Parser<Input, Output = BlockExprNode>
where
Input: Stream<Token = char>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
satisfy(|c: char| !c.is_control())
.map(|c| BlockExprNode::Char(c))
.message("while parsing char")
}
fn bold<Input>() -> impl Parser<Input, Output = BlockExprNode>
where
Input: Stream<Token = char>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
(token('*'), many1(block_expr_node()), token('*'))
.map(|(_, v, _)| BlockExprNode::Bold(v))
.message("while parsing bold")
}
I think this does not work because once it starts to parse in bold
, the many1(block_expr_node())
picks char
and the input is consumed until EOF:
Error: Parse error at line: 1, column: 4
Unexpected end of input
Expected `*`
while parsing bold
while parsing char
while parsing block_expr_node
Replacing the bold
implementation with:
fn bold<Input>() -> impl Parser<Input, Output = BlockExprNode>
where
Input: Stream<Token = char>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
(
token('*'),
take_until::<String, _, _>(token('*')).map(|s| {
// HACK ouch ouch ouch
many1(block_expr_node())
.easy_parse(position::Stream::new(&s[..]))
// this is the except on Result
.expect("In bold subparser")
.0
}),
token('*'),
)
.map(|(_, v, _)| BlockExprNode::Bold(v))
.message("while parsing bold")
}
..parses correctly but is obviously messy and handling errors correctly as in #199 (comment) only adds more boilerplate. Do you think it could be possible to add an abstraction above flat_map
so this could be done like:
fn bold<Input>() -> impl Parser<Input, Output = BlockExprNode>
where
Input: Stream<Token = char>,
Input::Error: ParseError<Input::Token, Input::Range, Input::Position>,
{
(
token('*'),
take_until::<String, _, _>(token('*')).and_reparse_with(many1(block_expr_node()),
token('*'),
)
.map(|(_, v, _)| BlockExprNode::Bold(v))
.message("while parsing bold")
}
It'd still create the sub-parser in a flat_map
but would hide the scary types from me :P
Metadata
Metadata
Assignees
Labels
No labels