pub struct Parser<F, I>(/* private fields */);Expand description
This type is the one all functionality is built on.
The F type argument is the parser implementation, which is usually a function or a combinator
from combinators.
The I type argument is the expected input. If you write parsers, it is advised to make your
parser generic over the input, to allow different levels of tracking it, unless the parser
makes use of the type directly.
§Notes
All repeating combinators simply stop consuming the input if the given range is exceeded (should one be given). The behaviour, should that range be empty or from high to low, is, while not undefined, implementation defined and should not be relied upon.
Those repeating combinators are (note that the syntactic sugar variant always uses
Vec:
| combinator | has separator | has range | returns outputs | returns count | syntactic sugar |
|---|---|---|---|---|---|
counted_separated | yes | yes | yes | yes | none |
separated | yes | yes | yes | no | / sep * new_collection * range |
const_separated | yes | one number | yes | no | none |
count_separated_within | yes | yes | no | yes | none |
count_separated | yes | no | no | yes | none |
counted_repeat | no | yes | yes | yes | none |
repeat | no | yes | yes | no | * new_collection * range |
const_repeat | no | one number | yes | no | none |
count_within | no | yes | no | yes | none |
count | no | no | no | yes | none |
Combinators not found as methods:
epsilonor ε. Matches nothing, always succeeds.tag. Requires the input to start with the given subsequence/substring.fail_with. Always fails, generating the error using a closure.fail_with_const. Always fails, generating the error usingCloneon the given argument.eof. Fails if the input isn’t empty.not. Fails if the given parser succeeds, and succeeds if the given parser fails.consume_one_where. Consumes the first element/character of the input, if it matches a given condition.consume_while. Consumes elements/characters of the input that match the given condition. Its given a range, which acts like the range given to other repeating combinators.record_while. Likeconsume_while, but returns the matched substring.take. Consumes the rest of the input, and returns the matched string.lookahead. Outputs the result of the given parser without consuming it.output. Outputs the output of the given function, or fails if the function returnsErr.
Implementations§
Source§impl<F, I, O, E> Parser<F, I>
impl<F, I, O, E> Parser<F, I>
Sourcepub fn new(func: F) -> Self
pub fn new(func: F) -> Self
This function allows you to create a new parser. If you wrote your own type which
implements ParserImpl, use Parser::new_generic.
Source§impl<F, I, O, E> Parser<F, I>where
F: ParserImpl<I, Output = O, Error = E>,
impl<F, I, O, E> Parser<F, I>where
F: ParserImpl<I, Output = O, Error = E>,
Sourcepub fn new_generic(implementation: F) -> Self
pub fn new_generic(implementation: F) -> Self
This function allows you to create a new parser. It will not work with type inference for
closures though, so use Parser::new for those.
This function only exists to make the type inference for closures work in
new.
Sourcepub fn then<O2, F2>(
self,
next: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = (O, O2), Error = E>, I>where
F2: ParserImpl<I, Output = O2, Error = E>,
pub fn then<O2, F2>(
self,
next: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = (O, O2), Error = E>, I>where
F2: ParserImpl<I, Output = O2, Error = E>,
This returns a new parser, which applies this parser and the given one on the input in that
order, returning a pair of outputs. The syntactic sugar is
>>.
Sourcepub fn before<O2, F2>(
self,
main: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>where
F2: ParserImpl<I, Output = O2, Error = E>,
pub fn before<O2, F2>(
self,
main: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>where
F2: ParserImpl<I, Output = O2, Error = E>,
See Parser::then, this parser returns only the result of the parser which
was given as an argument. The syntactic sugar is
>> together with -, see
the top level documentation.
Sourcepub fn followed_by<F2>(
self,
next: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = O, Error = E>, I>where
F2: ParserImpl<I, Error = E>,
pub fn followed_by<F2>(
self,
next: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = O, Error = E>, I>where
F2: ParserImpl<I, Error = E>,
See Parser::then, this parser returns only the result of this parser. The
syntactic sugar is >> together with -,
see the top level documentation.
Sourcepub fn or<F2>(
self,
alt: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = O, Error = E>, I>
pub fn or<F2>( self, alt: Parser<F2, I>, ) -> Parser<impl ParserImpl<I, Output = O, Error = E>, I>
This returns a new parser, which tries to apply this parser, and, should this fail,
attempts to apply the one given as an argument. Should that also fail, it’ll return an
error. The syntactic sugar is |.
Sourcepub fn map_result<O2, F2>(
self,
f: F2,
) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>
pub fn map_result<O2, F2>( self, f: F2, ) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>
Sourcepub fn map<O2, F2>(
self,
f: F2,
) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>where
F2: Fn(O) -> O2,
pub fn map<O2, F2>(
self,
f: F2,
) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>where
F2: Fn(O) -> O2,
This returns a new parser, which maps the given function to the result of this parser. The
returned parser fails if this one does, and doesn’t fail if this one doesn’t. The syntactic
sugar is >>.
If you want to be able to induce failure, use map_result.
Sourcepub fn map_err<E2, F2>(
self,
f: F2,
) -> Parser<impl ParserImpl<I, Output = O, Error = E2>, I>where
F2: Fn(E) -> E2,
pub fn map_err<E2, F2>(
self,
f: F2,
) -> Parser<impl ParserImpl<I, Output = O, Error = E2>, I>where
F2: Fn(E) -> E2,
This returns a new parser, which maps the given function to the error of this parser, should it fail.
Sourcepub fn counted_separated<C, F2, R: RangeLike, CG>(
self,
range: R,
by: Parser<F2, I>,
collection_generator: CG,
) -> Parser<impl ParserImpl<I, Output = (C, usize), Error = E>, I>
pub fn counted_separated<C, F2, R: RangeLike, CG>( self, range: R, by: Parser<F2, I>, collection_generator: CG, ) -> Parser<impl ParserImpl<I, Output = (C, usize), Error = E>, I>
This returns a new parser, which collects a number of occurences which is in the given
range in the Collection C, and returns this collection and the number of
seen occurences in a pair.
Should this be impossible, it fails.
Please read the notes in the documentation for this type.
Sourcepub fn separated<C, F2, R: RangeLike, CG>(
self,
range: R,
by: Parser<F2, I>,
collection_generator: CG,
) -> Parser<impl ParserImpl<I, Output = C, Error = E>, I>
pub fn separated<C, F2, R: RangeLike, CG>( self, range: R, by: Parser<F2, I>, collection_generator: CG, ) -> Parser<impl ParserImpl<I, Output = C, Error = E>, I>
This returns a new parser, which collects a number of occurences which is in the given
range in the Collection C, and returns this collection.
Should this be impossible, it fails.
Please read the notes in the documentation for this type.
Sourcepub fn const_separated<C, F2, CG>(
self,
n: usize,
by: Parser<F2, I>,
collection_generator: CG,
) -> Parser<impl ParserImpl<I, Output = C, Error = E>, I>
pub fn const_separated<C, F2, CG>( self, n: usize, by: Parser<F2, I>, collection_generator: CG, ) -> Parser<impl ParserImpl<I, Output = C, Error = E>, I>
This returns a new parser, which collects a number of occurences which is equal to the
given argument in the Collection C, and returns this collection.
Should this be impossible, it fails.
Please read the notes in the documentation for this type.
Sourcepub fn count_separated_within<R: RangeLike, F2>(
self,
range: R,
by: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = usize, Error = E>, I>where
F2: ParserImpl<I, Error = E>,
I: Clone,
pub fn count_separated_within<R: RangeLike, F2>(
self,
range: R,
by: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = usize, Error = E>, I>where
F2: ParserImpl<I, Error = E>,
I: Clone,
This returns a new parser, which counts the number of occurences which has to be within the given range, and returns that number.
It only consumes the minimum of the amount of occurences there are and the upper bound, if there are less occurences than the lower bound, the returned parser fails.
Please read the notes in the documentation for this type.
Sourcepub fn count_separated<F2>(
self,
by: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = usize, Error = E>, I>where
F2: ParserImpl<I, Error = E>,
I: Clone,
pub fn count_separated<F2>(
self,
by: Parser<F2, I>,
) -> Parser<impl ParserImpl<I, Output = usize, Error = E>, I>where
F2: ParserImpl<I, Error = E>,
I: Clone,
This returns a new parser, which counts the number of occurences, and returns that number.
Please read the notes in the documentation for this type.
Sourcepub fn counted_repeat<C, R: RangeLike, CG>(
self,
range: R,
collection_generator: CG,
) -> Parser<impl ParserImpl<I, Output = (C, usize), Error = E>, I>
pub fn counted_repeat<C, R: RangeLike, CG>( self, range: R, collection_generator: CG, ) -> Parser<impl ParserImpl<I, Output = (C, usize), Error = E>, I>
counted_separated without a separator.
Please read the notes in the documentation for this type.
Sourcepub fn repeat<C, R: RangeLike, CG>(
self,
range: R,
collection_generator: CG,
) -> Parser<impl ParserImpl<I, Output = C, Error = E>, I>
pub fn repeat<C, R: RangeLike, CG>( self, range: R, collection_generator: CG, ) -> Parser<impl ParserImpl<I, Output = C, Error = E>, I>
Sourcepub fn const_repeat<C, CG>(
self,
n: usize,
collection_generator: CG,
) -> Parser<impl ParserImpl<I, Output = C, Error = E>, I>
pub fn const_repeat<C, CG>( self, n: usize, collection_generator: CG, ) -> Parser<impl ParserImpl<I, Output = C, Error = E>, I>
const_separated without a separator.
Please read the notes in the documentation for this type.
Sourcepub fn count_within<R: RangeLike>(
self,
range: R,
) -> Parser<impl ParserImpl<I, Output = usize, Error = E>, I>where
I: Clone,
pub fn count_within<R: RangeLike>(
self,
range: R,
) -> Parser<impl ParserImpl<I, Output = usize, Error = E>, I>where
I: Clone,
count_separated_within without a separator.
Please read the notes in the documentation for this type.
Sourcepub fn count(self) -> Parser<impl ParserImpl<I, Output = usize, Error = E>, I>where
I: Clone,
pub fn count(self) -> Parser<impl ParserImpl<I, Output = usize, Error = E>, I>where
I: Clone,
count_separated without a separator.
Please read the notes in the documentation for this type.
Sourcepub fn maybe(
self,
) -> Parser<impl ParserImpl<I, Output = Option<O>, Error = E>, I>where
I: Clone,
pub fn maybe(
self,
) -> Parser<impl ParserImpl<I, Output = Option<O>, Error = E>, I>where
I: Clone,
Sourcepub fn record(
self,
) -> Parser<impl ParserImpl<I, Output = I::Output, Error = E>, I>where
I: Clone + Recordable,
pub fn record(
self,
) -> Parser<impl ParserImpl<I, Output = I::Output, Error = E>, I>where
I: Clone + Recordable,
This returns a parser which runs this parser, yielding the range of input that this parser consumed. It returns error should the inner parser fail.
Examples found in repository?
73 fn float(i: ParserInput) -> ParserResult<f32> {
74 (
75 (
76 -(cf::tag("-") | ())
77 >> (
78 -cf::tag(".") >> -consume_digits(1..) >> cf::epsilon()
79 |
80 -consume_digits(1..) >> (
81 -cf::tag(".") >> -consume_digits(0..) >> -(cf::f(float_e) | ()) >> cf::epsilon()
82 |
83 -cf::f(float_e) >> cf::epsilon()
84 )
85 )
86 ).record()
87 >> (|s: &str| s.parse::<f32>().unwrap())
88 ).parse_partial(i)
89 }
90
91 fn int(i: ParserInput) -> ParserResult<i32> {
92 (
93 (
94 -(cf::tag("-") | ())
95 >> cf::consume_while(|&c: &char| c.is_digit(10), 1..)
96 ).record()
97 >> (|s: &str| s.parse::<i32>().unwrap())
98 ).parse_partial(i)
99 }Sourcepub fn convert_err<E2>(
self,
) -> Parser<impl ParserImpl<I, Output = O, Error = E2>, I>where
E2: From<E>,
pub fn convert_err<E2>(
self,
) -> Parser<impl ParserImpl<I, Output = O, Error = E2>, I>where
E2: From<E>,
This converts the error to another one using .into, should this parser
fail.
Sourcepub fn map_range_and_out<O2, F2>(
self,
f: F2,
) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>
pub fn map_range_and_out<O2, F2>( self, f: F2, ) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>
This calls the given function with the input left before and after this parser was run, together with the result of running it. The output of the resulting parser is the output of that function.
Sourcepub fn map_parser<O2, F2, F3>(
self,
f: F2,
) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>
pub fn map_parser<O2, F2, F3>( self, f: F2, ) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>
This runs a parser based on the output of this parser.
Note that the returned parser has to have a one type, you can achieve this (if your parser doesn’t just use the output for ranges or in closures) by defining those parsers as standalone functions.
Sourcepub fn borrowed<'a>(
&'a self,
) -> Parser<impl ParserImpl<I, Output = O, Error = E> + 'a, I>
pub fn borrowed<'a>( &'a self, ) -> Parser<impl ParserImpl<I, Output = O, Error = E> + 'a, I>
Borrows this parser, allowing it to be combined with other parsers without being moved.
Sourcepub fn parse_partial(&self, input: I) -> Result<(I, O), E>
pub fn parse_partial(&self, input: I) -> Result<(I, O), E>
Parses as far as it can parse. This is just a wrapper around
ParserImpl::apply.
See that function for more documentation.
Examples found in repository?
46fn parse_partial(i: ParserInput) -> ParserResult<Value> {
47 fn string(i: ParserInput) -> ParserResult<String> {
48 (
49 -cf::tag("\"")
50 >> cf::record_while(|&c: &char| c != '"', ..)
51 >> -cf::tag("\"")
52 >> ToOwned::to_owned
53 ).parse_partial(i)
54 }
55
56 fn consume_digits<'a, R: cf::RangeLike>(range: R) -> cf::parser!(<ParserInput<'a>, (), ParserError<'a>>) {
57 cf::consume_while(|&c: &char| c.is_digit(10), range)
58 }
59
60 fn float_e(i: ParserInput) -> ParserResult<()> {
61 (
62 -cf::tag("e")
63 >> -(cf::tag("-") | ())
64 >> -consume_digits(1..)
65 >> cf::epsilon()
66 ).parse_partial(i)
67 }
68
69 // NOTE: You could combine `float` and `int` to one parser that may return either, by capturing
70 // wether or not an "e" or a dot occured, and choosing the right method based on that.
71 // Actually, we already have the handy `Number` type below anyways.
72
73 fn float(i: ParserInput) -> ParserResult<f32> {
74 (
75 (
76 -(cf::tag("-") | ())
77 >> (
78 -cf::tag(".") >> -consume_digits(1..) >> cf::epsilon()
79 |
80 -consume_digits(1..) >> (
81 -cf::tag(".") >> -consume_digits(0..) >> -(cf::f(float_e) | ()) >> cf::epsilon()
82 |
83 -cf::f(float_e) >> cf::epsilon()
84 )
85 )
86 ).record()
87 >> (|s: &str| s.parse::<f32>().unwrap())
88 ).parse_partial(i)
89 }
90
91 fn int(i: ParserInput) -> ParserResult<i32> {
92 (
93 (
94 -(cf::tag("-") | ())
95 >> cf::consume_while(|&c: &char| c.is_digit(10), 1..)
96 ).record()
97 >> (|s: &str| s.parse::<i32>().unwrap())
98 ).parse_partial(i)
99 }
100
101 fn list(i: ParserInput) -> ParserResult<Vec<Value>> {
102 (
103 -cf::tag("(")
104 >> cf::f(parse_partial) / sp::ws(1..) * Vec::new * ..
105 >> -sp::ws(..)
106 >> -cf::tag(")")
107 ).parse_partial(i)
108 }
109
110 (
111 -sp::ws(..)
112 >> (
113 cf::f(string) >> Value::Str
114 | cf::f(float) >> Value::Float
115 | cf::f(int) >> Value::Int
116 | cf::f(list) >> Value::List
117 )
118 ).parse_partial(i)
119}