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?
5fn main() {
6 // Informal, Spanish-language movie database format
7 let input = "\
8Título: Abre los ojos
9Año: 1997
10Director: Alejandro Amenábar
11
12Título: Amores Perros
13Director: Alejandro González Iñárritu
14Año: 2000
15
16Título: La montaña sagrada
17Año: 1973
18Director: Alejandro Jodorowsky
19";
20
21 enum DataLine<'a> {
22 Title(&'a str),
23 Director(&'a str),
24 Year(i32),
25 }
26
27 fn positive<'a>() -> Parser<'a, i32> {
28 // let integer = (one_of("123456789") - one_of("0123456789").repeat(0..)) | sym(b'0'); // TODO
29 let digit = one_of("0123456789");
30 let integer = digit.discard().repeat(1..);
31 integer.collect().convert(|x| x.parse::<i32>())
32 }
33
34 fn rest_str<'a>() -> Parser<'a, &'a str> {
35 any().repeat(1..).collect()
36 }
37
38 fn separator<'a>() -> Parser<'a, ()> {
39 seq(": ").discard()
40 }
41
42 let parser = (seq("Título") * separator() * rest_str().map(|s| DataLine::Title(s)))
43 | (seq("Director") * separator() * rest_str().map(|s| DataLine::Director(s)))
44 | (seq("Año") * separator() * positive().map(|i| DataLine::Year(i)));
45
46 {
47 let mut title_opt: Option<&str> = None;
48 let mut year_opt: Option<i32> = None;
49 let mut director_opt: Option<&str> = None;
50
51 for line in input.lines() {
52 if !line.is_empty() {
53 // Skip blank lines without parsing
54 // Parse line
55 match parser.parse_str(line).unwrap() {
56 DataLine::Title(s) => title_opt = Some(s),
57 DataLine::Director(s) => director_opt = Some(s),
58 DataLine::Year(s) => year_opt = Some(s),
59 }
60 // When all three line types have been collected, print them
61 if let (Some(title), Some(year), Some(director)) =
62 (title_opt, year_opt, director_opt)
63 {
64 println!("Title: {}\nDirector: {}\nYear: {}\n", title, director, year);
65 (title_opt, year_opt, director_opt) = (None, None, None);
66 }
67 }
68 }
69 }
70}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?
5fn main() {
6 // Informal, Spanish-language movie database format
7 let input = "\
8Título: Abre los ojos
9Año: 1997
10Director: Alejandro Amenábar
11
12Título: Amores Perros
13Director: Alejandro González Iñárritu
14Año: 2000
15
16Título: La montaña sagrada
17Año: 1973
18Director: Alejandro Jodorowsky
19";
20
21 enum DataLine<'a> {
22 Title(&'a str),
23 Director(&'a str),
24 Year(i32),
25 }
26
27 fn positive<'a>() -> Parser<'a, i32> {
28 // let integer = (one_of("123456789") - one_of("0123456789").repeat(0..)) | sym(b'0'); // TODO
29 let digit = one_of("0123456789");
30 let integer = digit.discard().repeat(1..);
31 integer.collect().convert(|x| x.parse::<i32>())
32 }
33
34 fn rest_str<'a>() -> Parser<'a, &'a str> {
35 any().repeat(1..).collect()
36 }
37
38 fn separator<'a>() -> Parser<'a, ()> {
39 seq(": ").discard()
40 }
41
42 let parser = (seq("Título") * separator() * rest_str().map(|s| DataLine::Title(s)))
43 | (seq("Director") * separator() * rest_str().map(|s| DataLine::Director(s)))
44 | (seq("Año") * separator() * positive().map(|i| DataLine::Year(i)));
45
46 {
47 let mut title_opt: Option<&str> = None;
48 let mut year_opt: Option<i32> = None;
49 let mut director_opt: Option<&str> = None;
50
51 for line in input.lines() {
52 if !line.is_empty() {
53 // Skip blank lines without parsing
54 // Parse line
55 match parser.parse_str(line).unwrap() {
56 DataLine::Title(s) => title_opt = Some(s),
57 DataLine::Director(s) => director_opt = Some(s),
58 DataLine::Year(s) => year_opt = Some(s),
59 }
60 // When all three line types have been collected, print them
61 if let (Some(title), Some(year), Some(director)) =
62 (title_opt, year_opt, director_opt)
63 {
64 println!("Title: {}\nDirector: {}\nYear: {}\n", title, director, year);
65 (title_opt, year_opt, director_opt) = (None, None, None);
66 }
67 }
68 }
69 }
70}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 fn positive<'a>() -> Parser<'a, i32> {
28 // let integer = (one_of("123456789") - one_of("0123456789").repeat(0..)) | sym(b'0'); // TODO
29 let digit = one_of("0123456789");
30 let integer = digit.discard().repeat(1..);
31 integer.collect().convert(|x| x.parse::<i32>())
32 }
33
34 fn rest_str<'a>() -> Parser<'a, &'a str> {
35 any().repeat(1..).collect()
36 }
37
38 fn separator<'a>() -> Parser<'a, ()> {
39 seq(": ").discard()
40 }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>
Sequence reserve value
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>
Sequence reserve value (but degrade to non-utf8 parser)
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>
Sequence reserve value (but degrade to non-utf8 parser)
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>
Ordered choice (but degrade to non-utf8 parser)
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>
Ordered choice (but degrade to non-utf8 parser)
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>
Sequence discard first value
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>
Sequence discard first value (but degrade to non-utf8 parser)
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>
Sequence discard first value (but degrade to non-utf8 parser)
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>
Chain two parsers where the second parser depends on the first’s result.
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>
Sequence discard second value
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>
Sequence discard second value (but degrade to non-utf8 parser)
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)