refactor(parser): Switch 'consumed' from free to trait method

This commit is contained in:
Ed Page 2024-07-17 14:25:37 -05:00
parent df4e586271
commit dadf98e965
4 changed files with 23 additions and 22 deletions

View File

@ -5,7 +5,7 @@ use winnow::Parser;
use winnow::branch::alt; use winnow::branch::alt;
use winnow::bytes::take_till0; use winnow::bytes::take_till0;
use winnow::character::digit1; use winnow::character::digit1;
use winnow::combinator::{consumed, cut_err, fail, map, not, opt, peek, value}; use winnow::combinator::{cut_err, fail, map, not, opt, peek, value};
use winnow::error::{ErrorKind, ParseError as _}; use winnow::error::{ErrorKind, ParseError as _};
use winnow::multi::{fold_many0, many0, separated0, separated1}; use winnow::multi::{fold_many0, many0, separated0, separated1};
use winnow::sequence::{preceded, terminated}; use winnow::sequence::{preceded, terminated};
@ -356,7 +356,7 @@ impl<'a> Expr<'a> {
fn num(i: &'a str) -> ParseResult<'a, WithSpan<'a, Self>> { fn num(i: &'a str) -> ParseResult<'a, WithSpan<'a, Self>> {
let start = i; let start = i;
let (i, (full, num)) = consumed(num_lit).parse_next(i)?; let (i, (num, full)) = num_lit.with_recognized().parse_next(i)?;
Ok((i, WithSpan::new(Expr::NumLit(full, num), start))) Ok((i, WithSpan::new(Expr::NumLit(full, num), start)))
} }

View File

@ -14,7 +14,7 @@ use winnow::Parser;
use winnow::branch::alt; use winnow::branch::alt;
use winnow::bytes::{any, one_of, tag, take_till0, take_till1, take_while_m_n, take_while1}; use winnow::bytes::{any, one_of, tag, take_till0, take_till1, take_while_m_n, take_while1};
use winnow::character::escaped; use winnow::character::escaped;
use winnow::combinator::{consumed, cut_err, fail, map, not, opt, value}; use winnow::combinator::{cut_err, fail, map, not, opt, value};
use winnow::error::{ErrorKind, FromExternalError}; use winnow::error::{ErrorKind, FromExternalError};
use winnow::multi::{many0, many1}; use winnow::multi::{many0, many1};
use winnow::sequence::{delimited, preceded}; use winnow::sequence::{delimited, preceded};
@ -371,11 +371,9 @@ fn num_lit<'a>(start: &'a str) -> ParseResult<'a, Num<'a>> {
// Equivalent to <https://github.com/rust-lang/rust/blob/e3f909b2bbd0b10db6f164d466db237c582d3045/compiler/rustc_lexer/src/lib.rs#L587-L620>. // Equivalent to <https://github.com/rust-lang/rust/blob/e3f909b2bbd0b10db6f164d466db237c582d3045/compiler/rustc_lexer/src/lib.rs#L587-L620>.
let int_with_base = (opt('-'), |i| { let int_with_base = (opt('-'), |i| {
let (i, (kind, base)) = consumed(preceded( let (i, (base, kind)) = preceded('0', alt((value(2, 'b'), value(8, 'o'), value(16, 'x'))))
'0', .with_recognized()
alt((value(2, 'b'), value(8, 'o'), value(16, 'x'))), .parse_next(i)?;
))
.parse_next(i)?;
match opt(separated_digits(base, false)).parse_next(i)? { match opt(separated_digits(base, false)).parse_next(i)? {
(i, Some(_)) => Ok((i, ())), (i, Some(_)) => Ok((i, ())),
(_, None) => Err(winnow::error::ErrMode::Cut(ErrorContext::new( (_, None) => Err(winnow::error::ErrMode::Cut(ErrorContext::new(
@ -411,9 +409,9 @@ fn num_lit<'a>(start: &'a str) -> ParseResult<'a, Num<'a>> {
opt(|i| num_lit_suffix("integer", INTEGER_TYPES, start, i)).parse_next(i)?; opt(|i| num_lit_suffix("integer", INTEGER_TYPES, start, i)).parse_next(i)?;
(i, Num::Int(num, suffix)) (i, Num::Int(num, suffix))
} else { } else {
let (i, (num, float)) = let (i, (float, num)) = preceded((opt('-'), separated_digits(10, true)), opt(float))
consumed(preceded((opt('-'), separated_digits(10, true)), opt(float))) .with_recognized()
.parse_next(start)?; .parse_next(start)?;
if float.is_some() { if float.is_some() {
let (i, suffix) = let (i, suffix) =
opt(|i| num_lit_suffix("float", FLOAT_TYPES, start, i)).parse_next(i)?; opt(|i| num_lit_suffix("float", FLOAT_TYPES, start, i)).parse_next(i)?;

View File

@ -3,7 +3,7 @@ use std::str;
use winnow::Parser; use winnow::Parser;
use winnow::branch::alt; use winnow::branch::alt;
use winnow::bytes::{any, tag, take_till0}; use winnow::bytes::{any, tag, take_till0};
use winnow::combinator::{consumed, cut_err, eof, fail, map, map_opt, not, opt, peek, value}; use winnow::combinator::{cut_err, eof, fail, map, map_opt, not, opt, peek, value};
use winnow::multi::{many0, separated0, separated1}; use winnow::multi::{many0, separated0, separated1};
use winnow::sequence::{delimited, preceded}; use winnow::sequence::{delimited, preceded};
@ -293,7 +293,7 @@ impl<'a> When<'a> {
fn when(i: &'a str, s: &State<'_>) -> ParseResult<'a, WithSpan<'a, Self>> { fn when(i: &'a str, s: &State<'_>) -> ParseResult<'a, WithSpan<'a, Self>> {
let start = i; let start = i;
let endwhen = map( let endwhen = map(
consumed(ws(( ws((
delimited( delimited(
|i| s.tag_block_start(i), |i| s.tag_block_start(i),
opt(Whitespace::parse), opt(Whitespace::parse),
@ -307,8 +307,9 @@ impl<'a> When<'a> {
many0(value((), ws(|i| Comment::parse(i, s)))).map(|()| ()), many0(value((), ws(|i| Comment::parse(i, s)))).map(|()| ()),
), ),
), ),
))), ))
|(span, (pws, _))| { .with_recognized(),
|((pws, _), span)| {
// A comment node is used to pass the whitespace suppressing information to the // A comment node is used to pass the whitespace suppressing information to the
// generator. This way we don't have to fix up the next `when` node or the closing // generator. This way we don't have to fix up the next `when` node or the closing
// `endmatch`. Any whitespaces after `endwhen` are to be suppressed. Actually, they // `endmatch`. Any whitespaces after `endwhen` are to be suppressed. Actually, they
@ -1055,12 +1056,12 @@ impl<'a> Raw<'a> {
( (
opt(Whitespace::parse), opt(Whitespace::parse),
|i| s.tag_block_end(i), |i| s.tag_block_end(i),
consumed(skip_till(Splitter1::new(s.syntax.block_start), endraw)), skip_till(Splitter1::new(s.syntax.block_start), endraw).with_recognized(),
), ),
), ),
); );
let (_, (pws1, _, (nws1, _, (contents, (i, (_, pws2, _, nws2, _)))))) = p.parse_next(i)?; let (_, (pws1, _, (nws1, _, ((i, (_, pws2, _, nws2, _)), contents)))) = p.parse_next(i)?;
let lit = Lit::split_ws_parts(contents); let lit = Lit::split_ws_parts(contents);
let ws1 = Ws(pws1, nws1); let ws1 = Ws(pws1, nws1);
let ws2 = Ws(pws2, nws2); let ws2 = Ws(pws2, nws2);

View File

@ -1,7 +1,7 @@
use winnow::Parser; use winnow::Parser;
use winnow::branch::alt; use winnow::branch::alt;
use winnow::bytes::one_of; use winnow::bytes::one_of;
use winnow::combinator::{consumed, map, map_res, opt}; use winnow::combinator::{map, map_res, opt};
use winnow::multi::separated1; use winnow::multi::separated1;
use winnow::sequence::preceded; use winnow::sequence::preceded;
@ -120,7 +120,9 @@ impl<'a> Target<'a> {
alt(( alt((
map(str_lit, Self::StrLit), map(str_lit, Self::StrLit),
map(char_lit, Self::CharLit), map(char_lit, Self::CharLit),
map(consumed(num_lit), |(full, num)| Target::NumLit(full, num)), map(num_lit.with_recognized(), |(num, full)| {
Target::NumLit(full, num)
}),
map(bool_lit, Self::BoolLit), map(bool_lit, Self::BoolLit),
)) ))
.parse_next(i) .parse_next(i)
@ -131,7 +133,7 @@ impl<'a> Target<'a> {
} }
fn named(init_i: &'a str, s: &State<'_>) -> ParseResult<'a, (&'a str, Self)> { fn named(init_i: &'a str, s: &State<'_>) -> ParseResult<'a, (&'a str, Self)> {
let (i, rest) = opt(consumed(Self::rest)).parse_next(init_i)?; let (i, rest) = opt(Self::rest.with_recognized()).parse_next(init_i)?;
if let Some(rest) = rest { if let Some(rest) = rest {
let (_, chr) = ws(opt(one_of(",:"))).parse_next(i)?; let (_, chr) = ws(opt(one_of(",:"))).parse_next(i)?;
if let Some(chr) = chr { if let Some(chr) = chr {
@ -143,7 +145,7 @@ impl<'a> Target<'a> {
i, i,
))); )));
} }
if let Target::Rest(ref s) = rest.1 { if let Target::Rest(ref s) = rest.0 {
if s.inner.is_some() { if s.inner.is_some() {
return Err(winnow::error::ErrMode::Cut(ErrorContext::new( return Err(winnow::error::ErrMode::Cut(ErrorContext::new(
"`@ ..` cannot be used in struct", "`@ ..` cannot be used in struct",
@ -151,7 +153,7 @@ impl<'a> Target<'a> {
))); )));
} }
} }
return Ok((i, rest)); return Ok((i, (rest.1, rest.0)));
} }
let (i, (src, target)) = let (i, (src, target)) =