pub struct Parser<'a, O>(/* private fields */);
Expand description
Being wrapped in this struct guarantees that the parser within will only match valid UTF-8 strings.
Implementations§
source§impl<'a, O> Parser<'a, O>
impl<'a, O> Parser<'a, O>
sourcepub fn collect(self) -> Parser<'a, &'a str>where
O: 'a,
pub fn collect(self) -> Parser<'a, &'a str>where
O: 'a,
Collect all matched input symbols.
Examples found in repository?
More examples
sourcepub fn parse_at(&self, input: &'a [u8], start: usize) -> Result<(O, usize)>
pub fn parse_at(&self, input: &'a [u8], start: usize) -> Result<(O, usize)>
Parse input at specified byte position.
sourcepub fn parse_str(&self, input: &'a str) -> Result<O>
pub fn parse_str(&self, input: &'a str) -> Result<O>
Apply the parser to parse input.
Examples found in repository?
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
fn main() {
// Informal, Spanish-language movie database format
let input = "\
Título: Abre los ojos
Año: 1997
Director: Alejandro Amenábar
Título: Amores Perros
Director: Alejandro González Iñárritu
Año: 2000
Título: La montaña sagrada
Año: 1973
Director: Alejandro Jodorowsky
";
enum DataLine<'a> {
Title(&'a str),
Director(&'a str),
Year(i32),
}
fn positive<'a>() -> Parser<'a, i32> {
// let integer = (one_of("123456789") - one_of("0123456789").repeat(0..)) | sym(b'0'); // TODO
let digit = one_of("0123456789");
let integer = digit.discard().repeat(1..);
integer.collect().convert(|x| x.parse::<i32>())
}
fn rest_str<'a>() -> Parser<'a, &'a str> {
any().repeat(1..).collect()
}
fn separator<'a>() -> Parser<'a, ()> {
seq(": ").discard()
}
let parser = (seq("Título") * separator() * rest_str().map(|s| DataLine::Title(s)))
| (seq("Director") * separator() * rest_str().map(|s| DataLine::Director(s)))
| (seq("Año") * separator() * positive().map(|i| DataLine::Year(i)));
{
let mut title_opt: Option<&str> = None;
let mut year_opt: Option<i32> = None;
let mut director_opt: Option<&str> = None;
for line in input.lines() {
if !line.is_empty() {
// Skip blank lines without parsing
// Parse line
match parser.parse_str(line).unwrap() {
DataLine::Title(s) => title_opt = Some(s),
DataLine::Director(s) => director_opt = Some(s),
DataLine::Year(s) => year_opt = Some(s),
}
// When all three line types have been collected, print them
if let (Some(title), Some(year), Some(director)) =
(title_opt, year_opt, director_opt)
{
println!("Title: {}\nDirector: {}\nYear: {}\n", title, director, year);
(title_opt, year_opt, director_opt) = (None, None, None);
}
}
}
}
}
sourcepub fn map<U, F>(self, f: F) -> Parser<'a, U>where
F: Fn(O) -> U + 'a,
O: 'a,
U: 'a,
pub fn map<U, F>(self, f: F) -> Parser<'a, U>where
F: Fn(O) -> U + 'a,
O: 'a,
U: 'a,
Convert parser result to desired value.
Examples found in repository?
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
fn main() {
// Informal, Spanish-language movie database format
let input = "\
Título: Abre los ojos
Año: 1997
Director: Alejandro Amenábar
Título: Amores Perros
Director: Alejandro González Iñárritu
Año: 2000
Título: La montaña sagrada
Año: 1973
Director: Alejandro Jodorowsky
";
enum DataLine<'a> {
Title(&'a str),
Director(&'a str),
Year(i32),
}
fn positive<'a>() -> Parser<'a, i32> {
// let integer = (one_of("123456789") - one_of("0123456789").repeat(0..)) | sym(b'0'); // TODO
let digit = one_of("0123456789");
let integer = digit.discard().repeat(1..);
integer.collect().convert(|x| x.parse::<i32>())
}
fn rest_str<'a>() -> Parser<'a, &'a str> {
any().repeat(1..).collect()
}
fn separator<'a>() -> Parser<'a, ()> {
seq(": ").discard()
}
let parser = (seq("Título") * separator() * rest_str().map(|s| DataLine::Title(s)))
| (seq("Director") * separator() * rest_str().map(|s| DataLine::Director(s)))
| (seq("Año") * separator() * positive().map(|i| DataLine::Year(i)));
{
let mut title_opt: Option<&str> = None;
let mut year_opt: Option<i32> = None;
let mut director_opt: Option<&str> = None;
for line in input.lines() {
if !line.is_empty() {
// Skip blank lines without parsing
// Parse line
match parser.parse_str(line).unwrap() {
DataLine::Title(s) => title_opt = Some(s),
DataLine::Director(s) => director_opt = Some(s),
DataLine::Year(s) => year_opt = Some(s),
}
// When all three line types have been collected, print them
if let (Some(title), Some(year), Some(director)) =
(title_opt, year_opt, director_opt)
{
println!("Title: {}\nDirector: {}\nYear: {}\n", title, director, year);
(title_opt, year_opt, director_opt) = (None, None, None);
}
}
}
}
}
sourcepub fn convert<U, E, F>(self, f: F) -> Parser<'a, U>
pub fn convert<U, E, F>(self, f: F) -> Parser<'a, U>
Convert parser result to desired value, fail in case of conversion error.
sourcepub fn cache(self) -> Selfwhere
O: Clone + 'a,
pub fn cache(self) -> Selfwhere
O: Clone + 'a,
Cache parser output result to speed up backtracking.
sourcepub fn discard(self) -> Parser<'a, ()>where
O: 'a,
pub fn discard(self) -> Parser<'a, ()>where
O: 'a,
Discard parser output.
Examples found in repository?
27 28 29 30 31 32 33 34 35 36 37 38 39 40
fn positive<'a>() -> Parser<'a, i32> {
// let integer = (one_of("123456789") - one_of("0123456789").repeat(0..)) | sym(b'0'); // TODO
let digit = one_of("0123456789");
let integer = digit.discard().repeat(1..);
integer.collect().convert(|x| x.parse::<i32>())
}
fn rest_str<'a>() -> Parser<'a, &'a str> {
any().repeat(1..).collect()
}
fn separator<'a>() -> Parser<'a, ()> {
seq(": ").discard()
}
sourcepub fn repeat<R>(self, range: R) -> Parser<'a, Vec<O>>
pub fn repeat<R>(self, range: R) -> Parser<'a, Vec<O>>
p.repeat(5)
repeat p exactly 5 times
p.repeat(0..)
repeat p zero or more times
p.repeat(1..)
repeat p one or more times
p.repeat(1..4)
match p at least 1 and at most 3 times
Examples found in repository?
More examples
Trait Implementations§
source§impl<'a, Left: 'a, Right: 'a> Add<Parser<'a, Right>> for Parser<'a, Left>
impl<'a, Left: 'a, Right: 'a> Add<Parser<'a, Right>> for Parser<'a, Left>
Sequence reserve value
source§impl<'a, Left: 'a, Right: 'a> Add<Parser<'a, Right>> for Parser<'a, u8, Left>
impl<'a, Left: 'a, Right: 'a> Add<Parser<'a, Right>> for Parser<'a, u8, Left>
Sequence reserve value (but degrade to non-utf8 parser)
source§impl<'a, Left: 'a, Right: 'a> Add<Parser<'a, u8, Right>> for Parser<'a, Left>
impl<'a, Left: 'a, Right: 'a> Add<Parser<'a, u8, Right>> for Parser<'a, Left>
Sequence reserve value (but degrade to non-utf8 parser)
source§impl<'a, O: 'a> BitOr<Parser<'a, O>> for Parser<'a, u8, O>
impl<'a, O: 'a> BitOr<Parser<'a, O>> for Parser<'a, u8, O>
Ordered choice (but degrade to non-utf8 parser)
source§impl<'a, O: 'a> BitOr<Parser<'a, u8, O>> for Parser<'a, O>
impl<'a, O: 'a> BitOr<Parser<'a, u8, O>> for Parser<'a, O>
Ordered choice (but degrade to non-utf8 parser)
source§impl<'a, Left: 'a, Right: 'a> Mul<Parser<'a, Right>> for Parser<'a, Left>
impl<'a, Left: 'a, Right: 'a> Mul<Parser<'a, Right>> for Parser<'a, Left>
Sequence discard first value
source§impl<'a, Left: 'a, Right: 'a> Mul<Parser<'a, Right>> for Parser<'a, u8, Left>
impl<'a, Left: 'a, Right: 'a> Mul<Parser<'a, Right>> for Parser<'a, u8, Left>
Sequence discard first value (but degrade to non-utf8 parser)
source§impl<'a, Left: 'a, Right: 'a> Mul<Parser<'a, u8, Right>> for Parser<'a, Left>
impl<'a, Left: 'a, Right: 'a> Mul<Parser<'a, u8, Right>> for Parser<'a, Left>
Sequence discard first value (but degrade to non-utf8 parser)
source§impl<'a, O: 'a, U: 'a, F: Fn(O) -> Parser<'a, U> + 'a> Shr<F> for Parser<'a, O>
impl<'a, O: 'a, U: 'a, F: Fn(O) -> Parser<'a, U> + 'a> Shr<F> for Parser<'a, O>
Chain two parsers where the second parser depends on the first’s result.
source§impl<'a, Left: 'a, Right: 'a> Sub<Parser<'a, Right>> for Parser<'a, Left>
impl<'a, Left: 'a, Right: 'a> Sub<Parser<'a, Right>> for Parser<'a, Left>
Sequence discard second value
source§impl<'a, Left: 'a, Right: 'a> Sub<Parser<'a, Right>> for Parser<'a, u8, Left>
impl<'a, Left: 'a, Right: 'a> Sub<Parser<'a, Right>> for Parser<'a, u8, Left>
Sequence discard second value (but degrade to non-utf8 parser)