Skip to content

Commit

Permalink
refactor: Move to merged parsers
Browse files Browse the repository at this point in the history
These were more entangled, so I didn't bother to do them by type.
  • Loading branch information
epage committed Dec 11, 2022
1 parent 5a3a6e8 commit e2de28d
Show file tree
Hide file tree
Showing 27 changed files with 310 additions and 271 deletions.
4 changes: 2 additions & 2 deletions examples/iterator.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::collections::HashMap;
use std::iter::Iterator;

use nom::bytes::complete::tag;
use nom::character::complete::alphanumeric1;
use nom::bytes::tag;
use nom::character::alphanumeric1;
use nom::combinator::iterator;
use nom::sequence::{separated_pair, terminated};
use nom::IResult;
Expand Down
6 changes: 3 additions & 3 deletions examples/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

use nom::{
branch::alt,
bytes::complete::{escaped, tag, take_while},
character::complete::{alphanumeric1 as alphanumeric, char, one_of},
bytes::{escaped, tag, take_while},
character::{alphanumeric1 as alphanumeric, char, one_of},
combinator::{cut, map, opt, value},
error::{context, convert_error, ContextError, ErrorKind, ParseError, VerboseError},
multi::separated_list0,
number::complete::double,
number::double,
sequence::{delimited, preceded, separated_pair, terminated},
Err, IResult,
};
Expand Down
130 changes: 64 additions & 66 deletions examples/json_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

use nom::{
branch::alt,
bytes::complete::{escaped, tag, take_while},
character::complete::{alphanumeric1 as alphanumeric, char, one_of},
combinator::{map, opt, cut},
bytes::{escaped, tag, take_while},
character::{alphanumeric1 as alphanumeric, char, one_of},
combinator::{cut, map, opt},
error::{context, ErrorKind, ParseError},
error::{VerboseError, VerboseErrorKind},
multi::separated_list,
number::complete::double,
number::double,
sequence::{delimited, preceded, separated_pair, terminated},
Err, IResult, Offset,
};
use std::collections::HashMap;

use std::str;
use std::cell::Cell;
use std::str;

struct Cursor<'a> {
inner: &'a str,
Expand All @@ -28,7 +28,7 @@ pub struct JsonValue<'a, 'b> {
pub offset: &'b Cell<usize>,
}

impl<'a, 'b:'a> JsonValue<'a, 'b> {
impl<'a, 'b: 'a> JsonValue<'a, 'b> {
pub fn new(input: &'a str, offset: &'b Cell<usize>) -> JsonValue<'a, 'b> {
JsonValue { input, offset }
}
Expand All @@ -49,7 +49,7 @@ impl<'a, 'b:'a> JsonValue<'a, 'b> {
self.offset(i);
println!("-> {}", s);
Some(s)
},
}
_ => None,
}
}
Expand All @@ -61,27 +61,27 @@ impl<'a, 'b:'a> JsonValue<'a, 'b> {
self.offset(i);
println!("-> {}", o);
Some(o)
},
}
_ => None,
}
}

pub fn number(&self) -> Option<f64> {
println!("number()");
match double::<_,()>(self.data()) {
match double::<_, ()>(self.data()) {
Ok((i, o)) => {
self.offset(i);
println!("-> {}", o);
Some(o)
},
}
_ => None,
}
}

pub fn array(&self) -> Option<impl Iterator<Item=JsonValue<'a, 'b>>> {
pub fn array(&self) -> Option<impl Iterator<Item = JsonValue<'a, 'b>>> {
println!("array()");

match tag::<_,_,()>("[")(self.data()) {
match tag::<_, _, ()>("[")(self.data()) {
Err(_) => None,
Ok((i, _)) => {
println!("[");
Expand All @@ -92,7 +92,7 @@ impl<'a, 'b:'a> JsonValue<'a, 'b> {

let v = self.clone();

Some(std::iter::from_fn(move|| {
Some(std::iter::from_fn(move || {
if done {
return None;
}
Expand All @@ -103,30 +103,29 @@ impl<'a, 'b:'a> JsonValue<'a, 'b> {
match value(v.data()) {
Ok((i, _)) => {
v.offset(i);
},
Err(_) => {},
}
Err(_) => {}
}
}


match tag::<_,_,()>("]")(v.data()) {
match tag::<_, _, ()>("]")(v.data()) {
Ok((i, _)) => {
println!("]");
v.offset(i);
done = true;
return None;
},
}
Err(_) => {}
};

if first {
first = false;
} else {
match tag::<_,_,()>(",")(v.data()) {
match tag::<_, _, ()>(",")(v.data()) {
Ok((i, _)) => {
println!(",");
println!(",");
v.offset(i);
},
}
Err(_) => {
done = true;
return None;
Expand All @@ -137,15 +136,14 @@ impl<'a, 'b:'a> JsonValue<'a, 'b> {
println!("-> {}", v.data());
previous = v.offset.get();
Some(v.clone())

}))
}
}
}

pub fn object(&self) -> Option<impl Iterator<Item=(&'a str, JsonValue<'a, 'b>)>> {
pub fn object(&self) -> Option<impl Iterator<Item = (&'a str, JsonValue<'a, 'b>)>> {
println!("object()");
match tag::<_,_,()>("{")(self.data()) {
match tag::<_, _, ()>("{")(self.data()) {
Err(_) => None,
Ok((i, _)) => {
self.offset(i);
Expand All @@ -158,7 +156,7 @@ impl<'a, 'b:'a> JsonValue<'a, 'b> {

let v = self.clone();

Some(std::iter::from_fn(move|| {
Some(std::iter::from_fn(move || {
if done {
return None;
}
Expand All @@ -169,29 +167,29 @@ impl<'a, 'b:'a> JsonValue<'a, 'b> {
match value(v.data()) {
Ok((i, _)) => {
v.offset(i);
},
Err(_) => {},
}
Err(_) => {}
}
}

match tag::<_,_,()>("}")(v.data()) {
match tag::<_, _, ()>("}")(v.data()) {
Ok((i, _)) => {
println!("}}");
v.offset(i);
done = true;
return None;
},
}
Err(_) => {}
};

if first {
first = false;
} else {
match tag::<_,_,()>(",")(v.data()) {
match tag::<_, _, ()>(",")(v.data()) {
Ok((i, _)) => {
println!(",");
v.offset(i);
},
}
Err(_) => {
done = true;
return None;
Expand All @@ -203,7 +201,7 @@ impl<'a, 'b:'a> JsonValue<'a, 'b> {
Ok((i, key)) => {
v.offset(i);

match tag::<_,_,()>(":")(v.data()) {
match tag::<_, _, ()>(":")(v.data()) {
Err(_) => None,
Ok((i, _)) => {
v.offset(i);
Expand All @@ -214,10 +212,9 @@ impl<'a, 'b:'a> JsonValue<'a, 'b> {
Some((key, v.clone()))
}
}
},
}
_ => None,
}

}))
}
}
Expand All @@ -235,47 +232,44 @@ fn parse_str<'a, E: ParseError<&'a str>>(i: &'a str) -> IResult<&'a str, &'a str
}

fn string<'a>(i: &'a str) -> IResult<&'a str, &'a str> {
context("string",
preceded(
char('\"'),
cut(terminated(
parse_str,
char('\"')
))))(i)
context(
"string",
preceded(char('\"'), cut(terminated(parse_str, char('\"')))),
)(i)
}

fn boolean<'a>(input: &'a str) -> IResult<&'a str, bool> {
alt((
map(tag("false"), |_| false),
map(tag("true"), |_| true)
))(input)
alt((map(tag("false"), |_| false), map(tag("true"), |_| true)))(input)
}

fn array<'a>(i: &'a str) -> IResult<&'a str, ()> {
context(
"array",
preceded(char('['),
cut(terminated(
map(separated_list(preceded(sp, char(',')), value), |_| ()),
preceded(sp, char(']'))))
))(i)
preceded(
char('['),
cut(terminated(
map(separated_list(preceded(sp, char(',')), value), |_| ()),
preceded(sp, char(']')),
)),
),
)(i)
}

fn key_value<'a>(i: &'a str) -> IResult<&'a str, (&'a str, ())> {
separated_pair(preceded(sp, string), cut(preceded(sp, char(':'))), value)(i)
separated_pair(preceded(sp, string), cut(preceded(sp, char(':'))), value)(i)
}

fn hash<'a>(i: &'a str) -> IResult<&'a str, ()> {
context(
"map",
preceded(char('{'),
cut(terminated(
map(
separated_list(preceded(sp, char(',')), key_value),
|_| ()),
preceded(sp, char('}')),
))
))(i)
preceded(
char('{'),
cut(terminated(
map(separated_list(preceded(sp, char(',')), key_value), |_| ()),
preceded(sp, char('}')),
)),
),
)(i)
}

fn value<'a>(i: &'a str) -> IResult<&'a str, ()> {
Expand Down Expand Up @@ -314,13 +308,17 @@ fn main() {
let parser = JsonValue::new(data, &offset);

if let Some(o) = parser.object() {
let s: HashMap<&str, &str> = o.filter(|(k,_)| *k == "users" )
.filter_map(|(_, v)| v.object()).flatten()
.filter_map(|(user, v)| v.object().map(|o| (user, o)))
.map(|(user, o)| {
o.filter(|(k,_)| *k == "city" )
.filter_map(move |(_, v)| v.string().map(|s| (user, s)))
}).flatten().collect();
let s: HashMap<&str, &str> = o
.filter(|(k, _)| *k == "users")
.filter_map(|(_, v)| v.object())
.flatten()
.filter_map(|(user, v)| v.object().map(|o| (user, o)))
.map(|(user, o)| {
o.filter(|(k, _)| *k == "city")
.filter_map(move |(_, v)| v.string().map(|s| (user, s)))
})
.flatten()
.collect();

println!("res = {:?}", s);
}
Expand Down
4 changes: 2 additions & 2 deletions examples/s_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

use nom::{
branch::alt,
bytes::complete::tag,
character::complete::{alpha1, char, digit1, multispace0, multispace1, one_of},
bytes::tag,
character::{alpha1, char, digit1, multispace0, multispace1, one_of},
combinator::{cut, map, map_res, opt},
error::{context, VerboseError},
multi::many0,
Expand Down
4 changes: 2 additions & 2 deletions examples/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#![cfg(feature = "alloc")]

use nom::branch::alt;
use nom::bytes::streaming::{is_not, take_while_m_n};
use nom::character::streaming::{char, multispace1};
use nom::bytes::{is_not, take_while_m_n};
use nom::character::{char, multispace1};
use nom::combinator::{map, map_opt, map_res, value, verify};
use nom::error::{FromExternalError, ParseError};
use nom::multi::fold_many0;
Expand Down
6 changes: 3 additions & 3 deletions src/branch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub trait Alt<I, O, E> {
/// ```rust
/// # use nom::error_position;
/// # use nom::{Err,error::ErrorKind, Needed, IResult};
/// use nom::character::complete::{alpha1, digit1};
/// use nom::character::{alpha1, digit1};
/// use nom::branch::alt;
/// # fn main() {
/// fn parser(input: &str) -> IResult<&str, &str> {
Expand Down Expand Up @@ -66,7 +66,7 @@ pub trait Permutation<I, O, E> {
///
/// ```rust
/// # use nom::{Err,error::{Error, ErrorKind}, Needed, IResult};
/// use nom::character::complete::{alpha1, digit1};
/// use nom::character::{alpha1, digit1};
/// use nom::branch::permutation;
/// # fn main() {
/// fn parser(input: &str) -> IResult<&str, (&str, &str)> {
Expand All @@ -89,7 +89,7 @@ pub trait Permutation<I, O, E> {
/// ```rust
/// # use nom::{Err, error::{Error, ErrorKind}, IResult};
/// use nom::branch::permutation;
/// use nom::character::complete::{anychar, char};
/// use nom::character::{anychar, char};
///
/// fn parser(input: &str) -> IResult<&str, (char, char)> {
/// permutation((anychar, char('a')))(input)
Expand Down
Loading

0 comments on commit e2de28d

Please sign in to comment.