Skip to content

Commit

Permalink
fix(multi): Replace repeat0/repeat1 with repeat
Browse files Browse the repository at this point in the history
This is a follow up to winnow-rs#241 for merging in the 0/1 variants

This is a step towards winnow-rs#98
  • Loading branch information
epage committed May 2, 2023
1 parent f8dc771 commit ab2a3e8
Show file tree
Hide file tree
Showing 21 changed files with 173 additions and 190 deletions.
14 changes: 7 additions & 7 deletions benches/contains_token.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use criterion::black_box;

use winnow::combinator::alt;
use winnow::combinator::repeat0;
use winnow::combinator::repeat;
use winnow::prelude::*;
use winnow::token::take_till1;
use winnow::token::take_while1;
Expand Down Expand Up @@ -55,22 +55,22 @@ fn contains_token(c: &mut criterion::Criterion) {

fn parser_str(input: &str) -> IResult<&str, usize> {
let contains = "0123456789";
repeat0(alt((take_while1(contains), take_till1(contains)))).parse_next(input)
repeat(0.., alt((take_while1(contains), take_till1(contains)))).parse_next(input)
}

fn parser_slice(input: &str) -> IResult<&str, usize> {
let contains = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'][..];
repeat0(alt((take_while1(contains), take_till1(contains)))).parse_next(input)
repeat(0.., alt((take_while1(contains), take_till1(contains)))).parse_next(input)
}

fn parser_array(input: &str) -> IResult<&str, usize> {
let contains = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
repeat0(alt((take_while1(contains), take_till1(contains)))).parse_next(input)
repeat(0.., alt((take_while1(contains), take_till1(contains)))).parse_next(input)
}

fn parser_tuple(input: &str) -> IResult<&str, usize> {
let contains = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
repeat0(alt((take_while1(contains), take_till1(contains)))).parse_next(input)
repeat(0.., alt((take_while1(contains), take_till1(contains)))).parse_next(input)
}

fn parser_closure_or(input: &str) -> IResult<&str, usize> {
Expand All @@ -86,12 +86,12 @@ fn parser_closure_or(input: &str) -> IResult<&str, usize> {
|| c == '8'
|| c == '9'
};
repeat0(alt((take_while1(contains), take_till1(contains)))).parse_next(input)
repeat(0.., alt((take_while1(contains), take_till1(contains)))).parse_next(input)
}

fn parser_closure_matches(input: &str) -> IResult<&str, usize> {
let contains = |c: char| matches!(c, '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9');
repeat0(alt((take_while1(contains), take_till1(contains)))).parse_next(input)
repeat(0.., alt((take_while1(contains), take_till1(contains)))).parse_next(input)
}

const CONTIGUOUS: &str = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
Expand Down
48 changes: 27 additions & 21 deletions examples/arithmetic/parser_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use winnow::prelude::*;
use winnow::{
ascii::{digit1 as digit, multispace0 as multispace},
combinator::alt,
combinator::repeat0,
combinator::repeat,
combinator::{delimited, preceded},
IResult,
};
Expand Down Expand Up @@ -46,33 +46,39 @@ impl Display for Expr {

pub fn expr(i: &str) -> IResult<&str, Expr> {
let (i, initial) = term(i)?;
let (i, remainder) = repeat0(alt((
|i| {
let (i, add) = preceded("+", term).parse_next(i)?;
Ok((i, (Oper::Add, add)))
},
|i| {
let (i, sub) = preceded("-", term).parse_next(i)?;
Ok((i, (Oper::Sub, sub)))
},
)))
let (i, remainder) = repeat(
0..,
alt((
|i| {
let (i, add) = preceded("+", term).parse_next(i)?;
Ok((i, (Oper::Add, add)))
},
|i| {
let (i, sub) = preceded("-", term).parse_next(i)?;
Ok((i, (Oper::Sub, sub)))
},
)),
)
.parse_next(i)?;

Ok((i, fold_exprs(initial, remainder)))
}

fn term(i: &str) -> IResult<&str, Expr> {
let (i, initial) = factor(i)?;
let (i, remainder) = repeat0(alt((
|i| {
let (i, mul) = preceded("*", factor).parse_next(i)?;
Ok((i, (Oper::Mul, mul)))
},
|i| {
let (i, div) = preceded("/", factor).parse_next(i)?;
Ok((i, (Oper::Div, div)))
},
)))
let (i, remainder) = repeat(
0..,
alt((
|i| {
let (i, mul) = preceded("*", factor).parse_next(i)?;
Ok((i, (Oper::Mul, mul)))
},
|i| {
let (i, div) = preceded("/", factor).parse_next(i)?;
Ok((i, (Oper::Div, div)))
},
)),
)
.parse_next(i)?;

Ok((i, fold_exprs(initial, remainder)))
Expand Down
6 changes: 3 additions & 3 deletions examples/http/parser.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use winnow::{ascii::line_ending, combinator::repeat1, token::take_while1, IResult, Parser};
use winnow::{ascii::line_ending, combinator::repeat, token::take_while1, IResult, Parser};

pub type Stream<'i> = &'i [u8];

Expand Down Expand Up @@ -44,7 +44,7 @@ pub fn parse(data: &[u8]) -> Option<Vec<(Request<'_>, Vec<Header<'_>>)>> {

fn request(input: Stream<'_>) -> IResult<Stream<'_>, (Request<'_>, Vec<Header<'_>>)> {
let (input, req) = request_line(input)?;
let (input, h) = repeat1(message_header).parse_next(input)?;
let (input, h) = repeat(1.., message_header).parse_next(input)?;
let (input, _) = line_ending(input)?;

Ok((input, (req, h)))
Expand Down Expand Up @@ -86,7 +86,7 @@ fn message_header_value(input: Stream<'_>) -> IResult<Stream<'_>, &[u8]> {
fn message_header(input: Stream<'_>) -> IResult<Stream<'_>, Header<'_>> {
let (input, name) = take_while1(is_token).parse_next(input)?;
let (input, _) = ':'.parse_next(input)?;
let (input, value) = repeat1(message_header_value).parse_next(input)?;
let (input, value) = repeat(1.., message_header_value).parse_next(input)?;

Ok((input, Header { name, value }))
}
Expand Down
6 changes: 3 additions & 3 deletions examples/http/parser_streaming.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use winnow::{
ascii::line_ending, combinator::repeat1, stream::Partial, token::take_while1, IResult, Parser,
ascii::line_ending, combinator::repeat, stream::Partial, token::take_while1, IResult, Parser,
};

pub type Stream<'i> = Partial<&'i [u8]>;
Expand Down Expand Up @@ -46,7 +46,7 @@ pub fn parse(data: &[u8]) -> Option<Vec<(Request<'_>, Vec<Header<'_>>)>> {

fn request(input: Stream<'_>) -> IResult<Stream<'_>, (Request<'_>, Vec<Header<'_>>)> {
let (input, req) = request_line(input)?;
let (input, h) = repeat1(message_header).parse_next(input)?;
let (input, h) = repeat(1.., message_header).parse_next(input)?;
let (input, _) = line_ending(input)?;

Ok((input, (req, h)))
Expand Down Expand Up @@ -88,7 +88,7 @@ fn message_header_value(input: Stream<'_>) -> IResult<Stream<'_>, &[u8]> {
fn message_header(input: Stream<'_>) -> IResult<Stream<'_>, Header<'_>> {
let (input, name) = take_while1(is_token).parse_next(input)?;
let (input, _) = ':'.parse_next(input)?;
let (input, value) = repeat1(message_header_value).parse_next(input)?;
let (input, value) = repeat(1.., message_header_value).parse_next(input)?;

Ok((input, Header { name, value }))
}
Expand Down
4 changes: 2 additions & 2 deletions examples/ini/bench.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use winnow::combinator::repeat0;
use winnow::combinator::repeat;
use winnow::prelude::*;

mod parser;
Expand Down Expand Up @@ -32,7 +32,7 @@ file=payroll.dat
\0";

fn acc(i: parser::Stream<'_>) -> IResult<parser::Stream<'_>, Vec<(&str, &str)>> {
repeat0(parser::key_value).parse_next(i)
repeat(0.., parser::key_value).parse_next(i)
}

let mut group = c.benchmark_group("ini keys and values");
Expand Down
15 changes: 9 additions & 6 deletions examples/ini/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ use winnow::prelude::*;
use winnow::{
ascii::{alphanumeric1 as alphanumeric, multispace0 as multispace, space0 as space},
combinator::opt,
combinator::repeat0,
combinator::repeat,
combinator::{delimited, separated_pair, terminated},
token::take_while0,
};

pub type Stream<'i> = &'i [u8];

pub fn categories(i: Stream<'_>) -> IResult<Stream<'_>, HashMap<&str, HashMap<&str, &str>>> {
repeat0(separated_pair(
category,
opt(multispace),
repeat0(terminated(key_value, opt(multispace))),
))
repeat(
0..,
separated_pair(
category,
opt(multispace),
repeat(0.., terminated(key_value, opt(multispace))),
),
)
.parse_next(i)
}

Expand Down
6 changes: 3 additions & 3 deletions examples/ini/parser_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ use winnow::prelude::*;
use winnow::{
ascii::{alphanumeric1 as alphanumeric, space0 as space},
combinator::opt,
combinator::repeat0,
combinator::repeat,
combinator::{delimited, terminated},
token::{take_till0, take_while0, take_while1},
};

pub type Stream<'i> = &'i str;

pub fn categories(input: Stream<'_>) -> IResult<Stream<'_>, HashMap<&str, HashMap<&str, &str>>> {
repeat0(category_and_keys).parse_next(input)
repeat(0.., category_and_keys).parse_next(input)
}

fn category_and_keys(i: Stream<'_>) -> IResult<Stream<'_>, (&str, HashMap<&str, &str>)> {
Expand All @@ -28,7 +28,7 @@ fn category(i: Stream<'_>) -> IResult<Stream<'_>, &str> {
}

fn keys_and_values(input: Stream<'_>) -> IResult<Stream<'_>, HashMap<&str, &str>> {
repeat0(key_value).parse_next(input)
repeat(0.., key_value).parse_next(input)
}

fn key_value(i: Stream<'_>) -> IResult<Stream<'_>, (&str, &str)> {
Expand Down
6 changes: 3 additions & 3 deletions examples/s_expression/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use winnow::{
ascii::{alpha1, digit1, multispace0, multispace1},
combinator::alt,
combinator::repeat0,
combinator::repeat,
combinator::{cut_err, opt},
combinator::{delimited, preceded, terminated},
error::VerboseError,
Expand Down Expand Up @@ -168,7 +168,7 @@ fn parse_keyword(i: &str) -> IResult<&str, Atom, VerboseError<&str>> {
/// tuples are themselves a parser, used to sequence parsers together, so we can translate this
/// directly and then map over it to transform the output into an `Expr::Application`
fn parse_application(i: &str) -> IResult<&str, Expr, VerboseError<&str>> {
let application_inner = (parse_expr, repeat0(parse_expr))
let application_inner = (parse_expr, repeat(0.., parse_expr))
.map(|(head, tail)| Expr::Application(Box::new(head), tail));
// finally, we wrap it in an s-expression
s_exp(application_inner).parse_next(i)
Expand Down Expand Up @@ -212,7 +212,7 @@ fn parse_quote(i: &str) -> IResult<&str, Expr, VerboseError<&str>> {
// this should look very straight-forward after all we've done:
// we find the `'` (quote) character, use cut_err to say that we're unambiguously
// looking for an s-expression of 0 or more expressions, and then parse them
preceded("'", cut_err(s_exp(repeat0(parse_expr))))
preceded("'", cut_err(s_exp(repeat(0.., parse_expr))))
.context("quote")
.map(Expr::Quote)
.parse_next(i)
Expand Down
39 changes: 18 additions & 21 deletions src/_topic/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,6 @@
//! string slice to an integer value is slightly simpler. You can also strip the `_` from the string
//! slice that is returned, which is demonstrated in the second hexadecimal number parser.
//!
//! If you wish to limit the number of digits in a valid integer literal, replace `repeat1` with
//! `repeat` in the recipes.
//!
//! #### Hexadecimal
//!
//! The parser outputs the string slice of the digits without the leading `0x`/`0X`.
Expand All @@ -157,7 +154,7 @@
//! use winnow::prelude::*;
//! use winnow::{
//! combinator::alt,
//! combinator::{repeat0, repeat1},
//! combinator::{repeat},
//! combinator::{preceded, terminated},
//! token::one_of,
//! token::tag,
Expand All @@ -166,8 +163,8 @@
//! fn hexadecimal(input: &str) -> IResult<&str, &str> { // <'a, E: ParseError<&'a str>>
//! preceded(
//! alt(("0x", "0X")),
//! repeat1(
//! terminated(one_of("0123456789abcdefABCDEF"), repeat0('_').map(|()| ()))
//! repeat(1..,
//! terminated(one_of("0123456789abcdefABCDEF"), repeat(0.., '_').map(|()| ()))
//! ).map(|()| ()).recognize()
//! ).parse_next(input)
//! }
Expand All @@ -179,7 +176,7 @@
//! use winnow::prelude::*;
//! use winnow::{
//! combinator::alt,
//! combinator::{repeat0, repeat1},
//! combinator::{repeat},
//! combinator::{preceded, terminated},
//! token::one_of,
//! token::tag,
Expand All @@ -188,8 +185,8 @@
//! fn hexadecimal_value(input: &str) -> IResult<&str, i64> {
//! preceded(
//! alt(("0x", "0X")),
//! repeat1(
//! terminated(one_of("0123456789abcdefABCDEF"), repeat0('_').map(|()| ()))
//! repeat(1..,
//! terminated(one_of("0123456789abcdefABCDEF"), repeat(0.., '_').map(|()| ()))
//! ).map(|()| ()).recognize()
//! ).try_map(
//! |out: &str| i64::from_str_radix(&str::replace(&out, "_", ""), 16)
Expand All @@ -203,7 +200,7 @@
//! use winnow::prelude::*;
//! use winnow::{
//! combinator::alt,
//! combinator::{repeat0, repeat1},
//! combinator::{repeat},
//! combinator::{preceded, terminated},
//! token::one_of,
//! token::tag,
Expand All @@ -212,8 +209,8 @@
//! fn octal(input: &str) -> IResult<&str, &str> {
//! preceded(
//! alt(("0o", "0O")),
//! repeat1(
//! terminated(one_of("01234567"), repeat0('_').map(|()| ()))
//! repeat(1..,
//! terminated(one_of("01234567"), repeat(0.., '_').map(|()| ()))
//! ).map(|()| ()).recognize()
//! ).parse_next(input)
//! }
Expand All @@ -225,7 +222,7 @@
//! use winnow::prelude::*;
//! use winnow::{
//! combinator::alt,
//! combinator::{repeat0, repeat1},
//! combinator::{repeat},
//! combinator::{preceded, terminated},
//! token::one_of,
//! token::tag,
Expand All @@ -234,8 +231,8 @@
//! fn binary(input: &str) -> IResult<&str, &str> {
//! preceded(
//! alt(("0b", "0B")),
//! repeat1(
//! terminated(one_of("01"), repeat0('_').map(|()| ()))
//! repeat(1..,
//! terminated(one_of("01"), repeat(0.., '_').map(|()| ()))
//! ).map(|()| ()).recognize()
//! ).parse_next(input)
//! }
Expand All @@ -247,14 +244,14 @@
//! use winnow::prelude::*;
//! use winnow::{
//! IResult,
//! combinator::{repeat0, repeat1},
//! combinator::{repeat},
//! combinator::terminated,
//! token::one_of,
//! };
//!
//! fn decimal(input: &str) -> IResult<&str, &str> {
//! repeat1(
//! terminated(one_of("0123456789"), repeat0('_').map(|()| ()))
//! repeat(1..,
//! terminated(one_of("0123456789"), repeat(0.., '_').map(|()| ()))
//! ).map(|()| ())
//! .recognize()
//! .parse_next(input)
Expand All @@ -269,7 +266,7 @@
//! use winnow::prelude::*;
//! use winnow::{
//! combinator::alt,
//! combinator::{repeat0, repeat1},
//! combinator::{repeat},
//! combinator::opt,
//! combinator::{preceded, terminated},
//! token::one_of,
Expand Down Expand Up @@ -308,8 +305,8 @@
//! }
//!
//! fn decimal(input: &str) -> IResult<&str, &str> {
//! repeat1(
//! terminated(one_of("0123456789"), repeat0('_').map(|()| ()))
//! repeat(1..,
//! terminated(one_of("0123456789"), repeat(0.., '_').map(|()| ()))
//! ).
//! map(|()| ())
//! .recognize()
Expand Down
Loading

0 comments on commit ab2a3e8

Please sign in to comment.