refactor(parser): Remove deprecated 'char' uses

This commit is contained in:
Ed Page 2024-07-16 12:13:24 -05:00
parent d171cdbaf1
commit 6ee949a9c6
4 changed files with 60 additions and 85 deletions

View File

@ -3,7 +3,7 @@ use std::str;
use winnow::branch::alt;
use winnow::bytes::complete::take_till;
use winnow::character::complete::{char, digit1};
use winnow::character::complete::digit1;
use winnow::combinator::{consumed, cut, fail, map, not, opt, peek, recognize, value};
use winnow::error::ErrorKind;
use winnow::multi::{fold_many0, many0, separated_list0, separated_list1};
@ -81,10 +81,10 @@ impl<'a> Expr<'a> {
let start = i;
preceded(
ws(char('(')),
ws('('),
cut(terminated(
separated_list0(
char(','),
',',
ws(move |i| {
// Needed to prevent borrowing it twice between this closure and the one
// calling `Self::named_arguments`.
@ -114,7 +114,7 @@ impl<'a> Expr<'a> {
}
}),
),
tuple((opt(ws(char(','))), char(')'))),
tuple((opt(ws(',')), ')')),
)),
)
.parse_next(i)
@ -135,7 +135,7 @@ impl<'a> Expr<'a> {
let (_, level) = level.nest(i)?;
let (i, (argument, _, value)) =
tuple((identifier, ws(char('=')), move |i| Self::parse(i, level))).parse_next(i)?;
tuple((identifier, ws('='), move |i| Self::parse(i, level))).parse_next(i)?;
if named_arguments.insert(argument) {
Ok((
i,
@ -292,28 +292,28 @@ impl<'a> Expr<'a> {
fn group(i: &'a str, level: Level) -> ParseResult<'a, WithSpan<'a, Self>> {
let (_, level) = level.nest(i)?;
let start = i;
let (i, expr) = preceded(ws(char('(')), opt(|i| Self::parse(i, level))).parse_next(i)?;
let (i, expr) = preceded(ws('('), opt(|i| Self::parse(i, level))).parse_next(i)?;
let Some(expr) = expr else {
let (i, _) = char(')').parse_next(i)?;
let (i, _) = ')'.parse_next(i)?;
return Ok((i, WithSpan::new(Self::Tuple(vec![]), start)));
};
let (i, comma) = ws(opt(peek(char(',')))).parse_next(i)?;
let (i, comma) = ws(opt(peek(','))).parse_next(i)?;
if comma.is_none() {
let (i, _) = char(')').parse_next(i)?;
let (i, _) = ')'.parse_next(i)?;
return Ok((i, WithSpan::new(Self::Group(Box::new(expr)), start)));
}
let mut exprs = vec![expr];
let (i, ()) = fold_many0(
preceded(char(','), ws(|i| Self::parse(i, level))),
preceded(',', ws(|i| Self::parse(i, level))),
|| (),
|(), expr| {
exprs.push(expr);
},
)
.parse_next(i)?;
let (i, _) = pair(ws(opt(char(','))), char(')')).parse_next(i)?;
let (i, _) = pair(ws(opt(',')), ')').parse_next(i)?;
Ok((i, WithSpan::new(Self::Tuple(exprs), start)))
}
@ -321,13 +321,13 @@ impl<'a> Expr<'a> {
let start = i;
let (i, level) = level.nest(i)?;
let (i, array) = preceded(
ws(char('[')),
ws('['),
cut(terminated(
opt(terminated(
separated_list1(char(','), ws(move |i| Self::parse(i, level))),
ws(opt(char(','))),
separated_list1(',', ws(move |i| Self::parse(i, level))),
ws(opt(',')),
)),
char(']'),
']',
)),
)
.parse_next(i)?;
@ -396,7 +396,7 @@ impl<'a> Expr<'a> {
}
fn token_xor(i: &str) -> ParseResult<'_> {
let (i, good) = alt((value(true, keyword("xor")), value(false, char('^')))).parse_next(i)?;
let (i, good) = alt((value(true, keyword("xor")), value(false, '^'))).parse_next(i)?;
if good {
Ok((i, "^"))
} else {
@ -410,7 +410,7 @@ fn token_xor(i: &str) -> ParseResult<'_> {
fn token_bitand(i: &str) -> ParseResult<'_> {
let (i, good) = alt((
value(true, keyword("bitand")),
value(false, pair(char('&'), not(char('&')))),
value(false, pair('&', not('&'))),
))
.parse_next(i)?;
if good {
@ -519,10 +519,10 @@ impl<'a> Suffix<'a> {
}
preceded(
pair(ws(char('!')), char('(')),
pair(ws('!'), '('),
cut(terminated(
map(recognize(nested_parenthesis), Self::MacroCall),
char(')'),
')',
)),
)
.parse_next(i)
@ -530,10 +530,7 @@ impl<'a> Suffix<'a> {
fn attr(i: &'a str) -> ParseResult<'a, Self> {
map(
preceded(
ws(pair(char('.'), not(char('.')))),
cut(alt((digit1, identifier))),
),
preceded(ws(pair('.', not('.'))), cut(alt((digit1, identifier)))),
Self::Attr,
)
.parse_next(i)
@ -543,8 +540,8 @@ impl<'a> Suffix<'a> {
let (_, level) = level.nest(i)?;
map(
preceded(
ws(char('[')),
cut(terminated(ws(move |i| Expr::parse(i, level)), char(']'))),
ws('['),
cut(terminated(ws(move |i| Expr::parse(i, level)), ']')),
),
Self::Index,
)
@ -557,6 +554,6 @@ impl<'a> Suffix<'a> {
}
fn r#try(i: &'a str) -> ParseResult<'a, Self> {
map(preceded(take_till(not_ws), char('?')), |_| Self::Try).parse_next(i)
map(preceded(take_till(not_ws), '?'), |_| Self::Try).parse_next(i)
}
}

View File

@ -13,7 +13,7 @@ use std::{fmt, str};
use winnow::Parser;
use winnow::branch::alt;
use winnow::bytes::complete::{escaped, is_not, tag, take_till, take_while_m_n, take_while1};
use winnow::character::complete::{anychar, char, one_of, satisfy};
use winnow::character::complete::{anychar, one_of, satisfy};
use winnow::combinator::{consumed, cut, fail, map, not, opt, recognize, value};
use winnow::error::{ErrorKind, FromExternalError};
use winnow::multi::{many0_count, many1};
@ -370,14 +370,10 @@ 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>.
let int_with_base = pair(opt(char('-')), |i| {
let int_with_base = pair(opt('-'), |i| {
let (i, (kind, base)) = consumed(preceded(
char('0'),
alt((
value(2, char('b')),
value(8, char('o')),
value(16, char('x')),
)),
'0',
alt((value(2, 'b'), value(8, 'o'), value(16, 'x'))),
))
.parse_next(i)?;
match opt(separated_digits(base, false)).parse_next(i)? {
@ -392,7 +388,7 @@ 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#L626-L653>:
// no `_` directly after the decimal point `.`, or between `e` and `+/-`.
let float = |i: &'a str| -> ParseResult<'a, ()> {
let (i, has_dot) = opt(pair(char('.'), separated_digits(10, true))).parse_next(i)?;
let (i, has_dot) = opt(pair('.', separated_digits(10, true))).parse_next(i)?;
let (i, has_exp) = opt(|i| {
let (i, (kind, op)) = pair(one_of("eE"), opt(one_of("+-"))).parse_next(i)?;
match opt(separated_digits(10, op.is_none())).parse_next(i)? {
@ -416,7 +412,7 @@ fn num_lit<'a>(start: &'a str) -> ParseResult<'a, Num<'a>> {
(i, Num::Int(num, suffix))
} else {
let (i, (num, float)) = consumed(preceded(
pair(opt(char('-')), separated_digits(10, true)),
pair(opt('-'), separated_digits(10, true)),
opt(float),
))
.parse_next(start)?;
@ -444,7 +440,7 @@ fn separated_digits(radix: u32, start: bool) -> impl Fn(&str) -> ParseResult<'_>
recognize(tuple((
|i| match start {
true => Ok((i, 0)),
false => many0_count(char('_')).parse_next(i),
false => many0_count('_').parse_next(i),
},
satisfy(|ch| ch.is_digit(radix)),
many0_count(satisfy(|ch| ch == '_' || ch.is_digit(radix))),
@ -484,18 +480,13 @@ pub struct StrLit<'a> {
}
fn str_lit_without_prefix(i: &str) -> ParseResult<'_> {
let (i, s) = delimited(
char('"'),
opt(escaped(is_not("\\\""), '\\', anychar)),
char('"'),
)
.parse_next(i)?;
let (i, s) = delimited('"', opt(escaped(is_not("\\\""), '\\', anychar)), '"').parse_next(i)?;
Ok((i, s.unwrap_or_default()))
}
fn str_lit(i: &str) -> Result<(&str, StrLit<'_>), ParseErr<'_>> {
let (i, (prefix, content)) =
tuple((opt(alt((char('b'), char('c')))), str_lit_without_prefix)).parse_next(i)?;
tuple((opt(alt(('b', 'c'))), str_lit_without_prefix)).parse_next(i)?;
let prefix = match prefix {
Some('b') => Some(StrPrefix::Binary),
Some('c') => Some(StrPrefix::CLike),
@ -520,12 +511,8 @@ pub struct CharLit<'a> {
fn char_lit(i: &str) -> Result<(&str, CharLit<'_>), ParseErr<'_>> {
let start = i;
let (i, (b_prefix, s)) = tuple((
opt(char('b')),
delimited(
char('\''),
opt(escaped(is_not("\\\'"), '\\', anychar)),
char('\''),
),
opt('b'),
delimited('\'', opt(escaped(is_not("\\\'"), '\\', anychar)), '\''),
))
.parse_next(i)?;
@ -597,28 +584,25 @@ impl<'a> Char<'a> {
}
map(
tuple((
char('\\'),
'\\',
alt((
map(char('n'), |_| Self::Escaped),
map(char('r'), |_| Self::Escaped),
map(char('t'), |_| Self::Escaped),
map(char('\\'), |_| Self::Escaped),
map(char('0'), |_| Self::Escaped),
map(char('\''), |_| Self::Escaped),
map('n', |_| Self::Escaped),
map('r', |_| Self::Escaped),
map('t', |_| Self::Escaped),
map('\\', |_| Self::Escaped),
map('0', |_| Self::Escaped),
map('\'', |_| Self::Escaped),
// Not useful but supported by rust.
map(char('"'), |_| Self::Escaped),
map('"', |_| Self::Escaped),
map(
tuple((
char('x'),
take_while_m_n(2, 2, |c: char| c.is_ascii_hexdigit()),
)),
tuple(('x', take_while_m_n(2, 2, |c: char| c.is_ascii_hexdigit()))),
|(_, s)| Self::AsciiEscape(s),
),
map(
tuple((
"u{",
take_while_m_n(1, 6, |c: char| c.is_ascii_hexdigit()),
char('}'),
'}',
)),
|(_, s, _)| Self::UnicodeEscape(s),
),
@ -900,7 +884,7 @@ fn filter<'a>(
) -> ParseResult<'a, (&'a str, Option<Vec<WithSpan<'a, Expr<'a>>>>)> {
let (j, _) = take_till(not_ws).parse_next(i)?;
let had_spaces = i.len() != j.len();
let (j, _) = pair(char('|'), not(char('|'))).parse_next(j)?;
let (j, _) = pair('|', not('|')).parse_next(j)?;
if !had_spaces {
*level = level.nest(i)?.1;

View File

@ -3,7 +3,7 @@ use std::str;
use winnow::Parser;
use winnow::branch::alt;
use winnow::bytes::complete::{tag, take_till};
use winnow::character::complete::{anychar, char};
use winnow::character::complete::anychar;
use winnow::combinator::{
complete, consumed, cut, eof, fail, map, map_opt, not, opt, peek, recognize, value,
};
@ -328,7 +328,7 @@ impl<'a> When<'a> {
cut_node(
Some("match-when"),
tuple((
separated_list1(char('|'), ws(|i| Target::parse(i, s))),
separated_list1('|', ws(|i| Target::parse(i, s))),
opt(Whitespace::parse),
|i| s.tag_block_end(i),
cut_node(Some("match-when"), |i| Node::many(i, s)),
@ -414,7 +414,7 @@ impl<'a> CondTest<'a> {
opt(delimited(
ws(alt((keyword("let"), keyword("set")))),
ws(|i| Target::parse(i, s)),
ws(char('=')),
ws('='),
)),
ws(|i| Expr::parse(i, s.level.get())),
)
@ -590,9 +590,9 @@ impl<'a> Macro<'a> {
fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, WithSpan<'a, Self>> {
fn parameters(i: &str) -> ParseResult<'_, Vec<&str>> {
delimited(
ws(char('(')),
separated_list0(char(','), ws(identifier)),
tuple((opt(ws(char(','))), char(')'))),
ws('('),
separated_list0(',', ws(identifier)),
tuple((opt(ws(',')), ')')),
)
.parse_next(i)
}
@ -1084,10 +1084,7 @@ impl<'a> Let<'a> {
Some("let"),
tuple((
ws(|i| Target::parse(i, s)),
opt(preceded(
ws(char('=')),
ws(|i| Expr::parse(i, s.level.get())),
)),
opt(preceded(ws('='), ws(|i| Expr::parse(i, s.level.get())))),
opt(Whitespace::parse),
)),
),

View File

@ -42,9 +42,9 @@ impl<'a> Target<'a> {
/// Parses a single target without an `or`, unless it is wrapped in parentheses.
fn parse_one(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {
let mut opt_opening_paren = map(opt(ws(char('('))), |o| o.is_some());
let mut opt_opening_brace = map(opt(ws(char('{'))), |o| o.is_some());
let mut opt_opening_bracket = map(opt(ws(char('['))), |o| o.is_some());
let mut opt_opening_paren = map(opt(ws('(')), |o| o.is_some());
let mut opt_opening_brace = map(opt(ws('{')), |o| o.is_some());
let mut opt_opening_bracket = map(opt(ws('[')), |o| o.is_some());
let (i, lit) = opt(Self::lit).parse_next(i)?;
if let Some(lit) = lit {
@ -154,10 +154,8 @@ impl<'a> Target<'a> {
return Ok((i, rest));
}
let (i, (src, target)) = pair(
identifier,
opt(preceded(ws(char(':')), |i| Self::parse(i, s))),
)(init_i)?;
let (i, (src, target)) =
pair(identifier, opt(preceded(ws(':'), |i| Self::parse(i, s))))(init_i)?;
if src == "_" {
return Err(winnow::Err::Cut(ErrorContext::new(
@ -174,8 +172,7 @@ impl<'a> Target<'a> {
}
fn rest(start: &'a str) -> ParseResult<'a, Self> {
let (i, (ident, _)) =
tuple((opt(tuple((identifier, ws(char('@'))))), "..")).parse_next(start)?;
let (i, (ident, _)) = tuple((opt(tuple((identifier, ws('@')))), "..")).parse_next(start)?;
Ok((
i,
Self::Rest(WithSpan::new(ident.map(|(ident, _)| ident), start)),
@ -202,7 +199,7 @@ fn collect_targets<'a, T>(
delim: char,
mut one: impl FnMut(&'a str, &State<'_>) -> ParseResult<'a, T>,
) -> ParseResult<'a, (bool, Vec<T>)> {
let opt_comma = |i| map(ws(opt(char(','))), |o| o.is_some()).parse_next(i);
let opt_comma = |i| map(ws(opt(',')), |o| o.is_some()).parse_next(i);
let mut opt_end = |i| map(ws(opt(char(delim))), |o| o.is_some()).parse_next(i);
let (i, has_end) = opt_end.parse_next(i)?;
@ -211,7 +208,7 @@ fn collect_targets<'a, T>(
}
let (i, targets) =
opt(separated_list1(ws(char(',')), |i| one(i, s)).map(|v: Vec<_>| v)).parse_next(i)?;
opt(separated_list1(ws(','), |i| one(i, s)).map(|v: Vec<_>| v)).parse_next(i)?;
let Some(targets) = targets else {
return Err(winnow::Err::Cut(ErrorContext::new(
"expected comma separated list of members",