Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Recipes had drifted from the implementation and weren't compiling #1695

Merged
merged 6 commits into from
Oct 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 24 additions & 15 deletions doc/nom_recipes.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Nom Recipes
# Common recipes to build nom parsers

These are short recipes for accomplishing common tasks with nom.

Expand Down Expand Up @@ -35,9 +35,9 @@ use nom::{

/// A combinator that takes a parser `inner` and produces a parser that also consumes both leading and
/// trailing whitespace, returning the output of `inner`.
fn ws<'a, F, O, E: ParseError<&'a str>>(inner: F) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>
fn ws<'a, F, O, E: ParseError<&'a str>>(inner: F) -> impl Parser<&'a str>
where
F: Parser<&'a str, O, E>,
F: Parser<&'a str>,
{
delimited(
multispace0,
Expand All @@ -62,6 +62,7 @@ output of `()`.
```rust
use nom::{
IResult,
Parser,
error::ParseError,
combinator::value,
sequence::pair,
Expand All @@ -74,7 +75,7 @@ pub fn peol_comment<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str,
value(
(), // Output is thrown away.
pair(char('%'), is_not("\n\r"))
)(i)
).parse(i)
}
```

Expand All @@ -86,6 +87,7 @@ and does not handle nested comments.
```rust
use nom::{
IResult,
Parser,
error::ParseError,
combinator::value,
bytes::complete::{tag, take_until},
Expand All @@ -99,7 +101,7 @@ pub fn pinline_comment<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a st
take_until("*)"),
tag("*)")
)
)(i)
).parse(i)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is required since #1631 has been merged.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nom is moving towards using traits instead of function as the main parser interface. You can still use functions though if you prefer

```

Expand All @@ -113,6 +115,7 @@ letters and numbers may be parsed like this:
```rust
use nom::{
IResult,
Parser,
branch::alt,
multi::many0_count,
combinator::recognize,
Expand All @@ -127,7 +130,7 @@ pub fn identifier(input: &str) -> IResult<&str, &str> {
alt((alpha1, tag("_"))),
many0_count(alt((alphanumeric1, tag("_"))))
)
)(input)
).parse(input)
}
```

Expand Down Expand Up @@ -164,6 +167,7 @@ The parser outputs the string slice of the digits without the leading `0x`/`0X`.
```rust
use nom::{
IResult,
Parser,
branch::alt,
multi::{many0, many1},
combinator::recognize,
Expand All @@ -180,7 +184,7 @@ fn hexadecimal(input: &str) -> IResult<&str, &str> { // <'a, E: ParseError<&'a s
terminated(one_of("0123456789abcdefABCDEF"), many0(char('_')))
)
)
)(input)
).parse(input)
}
```

Expand All @@ -189,6 +193,7 @@ If you want it to return the integer value instead, use map:
```rust
use nom::{
IResult,
Parser,
branch::alt,
multi::{many0, many1},
combinator::{map_res, recognize},
Expand All @@ -208,7 +213,7 @@ fn hexadecimal_value(input: &str) -> IResult<&str, i64> {
)
),
|out: &str| i64::from_str_radix(&str::replace(&out, "_", ""), 16)
)(input)
).parse(input)
}
```

Expand All @@ -217,6 +222,7 @@ fn hexadecimal_value(input: &str) -> IResult<&str, i64> {
```rust
use nom::{
IResult,
Parser,
branch::alt,
multi::{many0, many1},
combinator::recognize,
Expand All @@ -233,7 +239,7 @@ fn octal(input: &str) -> IResult<&str, &str> {
terminated(one_of("01234567"), many0(char('_')))
)
)
)(input)
).parse(input)
}
```

Expand All @@ -242,6 +248,7 @@ fn octal(input: &str) -> IResult<&str, &str> {
```rust
use nom::{
IResult,
Parser,
branch::alt,
multi::{many0, many1},
combinator::recognize,
Expand All @@ -258,7 +265,7 @@ fn binary(input: &str) -> IResult<&str, &str> {
terminated(one_of("01"), many0(char('_')))
)
)
)(input)
).parse(input)
}
```

Expand All @@ -267,6 +274,7 @@ fn binary(input: &str) -> IResult<&str, &str> {
```rust
use nom::{
IResult,
Parser,
multi::{many0, many1},
combinator::recognize,
sequence::terminated,
Expand All @@ -278,7 +286,7 @@ fn decimal(input: &str) -> IResult<&str, &str> {
many1(
terminated(one_of("0123456789"), many0(char('_')))
)
)(input)
).parse(input)
}
```

Expand All @@ -289,6 +297,7 @@ The following is adapted from [the Python parser by Valentin Lorentz (ProgVal)](
```rust
use nom::{
IResult,
Parser,
branch::alt,
multi::{many0, many1},
combinator::{opt, recognize},
Expand Down Expand Up @@ -331,15 +340,15 @@ fn float(input: &str) -> IResult<&str, &str> {
opt(decimal)
)
)
))(input)
)).parse(input)
}

fn decimal(input: &str) -> IResult<&str, &str> {
recognize(
many1(
terminated(one_of("0123456789"), many0(char('_')))
)
)(input)
).parse(input)
}
```

Expand All @@ -350,14 +359,14 @@ a common interface to parse from a string.

```rust
use nom::{
IResult, Finish, error::Error,
IResult, Parser, Finish, error::Error,
bytes::complete::{tag, take_while},
};
use std::str::FromStr;

// will recognize the name in "Hello, name!"
fn parse_name(input: &str) -> IResult<&str, &str> {
let (i, _) = tag("Hello, ")(input)?;
let (i, _) = tag("Hello, ").parse(input)?;
let (i, name) = take_while(|c:char| c.is_alphabetic())(i)?;
let (i, _) = tag("!")(i)?;

Expand Down
5 changes: 2 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,6 @@
//! check out the [recipes]!
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "docsrs", feature(doc_cfg))]
#![cfg_attr(feature = "docsrs", feature(extended_key_value_attributes))]
#![allow(clippy::doc_markdown)]
#![deny(missing_docs)]
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
Expand Down Expand Up @@ -463,6 +462,6 @@ mod str;

pub mod number;

#[cfg(feature = "docsrs")]
#[cfg_attr(feature = "docsrs", cfg_attr(feature = "docsrs", doc = include_str!("../doc/nom_recipes.md")))]
#[cfg(all(feature = "std", any(doc, doctest, feature = "docsrs")))]
#[cfg_attr(any(doc, doctest, feature = "docsrs"), doc = include_str!("../doc/nom_recipes.md"))]
pub mod recipes {}
Loading