Struct Parser

Source
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:

combinatorhas separatorhas rangereturns outputsreturns countsyntactic sugar
counted_separatedyesyesyesyesnone
separatedyesyesyesno/ sep * new_collection * range
const_separatedyesone numberyesnonone
count_separated_withinyesyesnoyesnone
count_separatedyesnonoyesnone
counted_repeatnoyesyesyesnone
repeatnoyesyesno* new_collection * range
const_repeatnoone numberyesnonone
count_withinnoyesnoyesnone
countnononoyesnone

Combinators not found as methods:

  • epsilon or ε. 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 using Clone on 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. Like consume_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 returns Err.

Implementations§

Source§

impl<F, I, O, E> Parser<F, I>
where F: Fn(I) -> Result<(I, O), E>,

Source

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>,

Source

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.

Source

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 >>.

Source

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.

Source

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.

Source

pub fn or<F2>( self, alt: Parser<F2, I>, ) -> Parser<impl ParserImpl<I, Output = O, Error = E>, I>
where F2: ParserImpl<I, Output = O, Error = E>, I: Clone, E: AltError<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 |.

Source

pub fn map_result<O2, F2>( self, f: F2, ) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>
where F2: Fn(O) -> Result<O2, E>,

This returns a new parser, which maps the given function to the result of this parser. This function returns a Result, so it can lead to the returned parser failing even if this one didn’t. The syntactic sugar is >> together with the wrapper type MapResult.

If your function never fails, use map.

Source

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.

Source

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.

Source

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>
where F2: ParserImpl<I, Error = E>, C: Collection<Item = O>, I: Clone, CG: Fn() -> C,

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.

Source

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>
where F2: ParserImpl<I, Error = E>, C: Collection<Item = O>, I: Clone, CG: Fn() -> C,

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.

Source

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>
where F2: ParserImpl<I, Error = E>, C: Collection<Item = O>, I: Clone, CG: Fn() -> C,

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.

Source

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.

Source

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.

Source

pub fn counted_repeat<C, R: RangeLike, CG>( self, range: R, collection_generator: CG, ) -> Parser<impl ParserImpl<I, Output = (C, usize), Error = E>, I>
where C: Collection<Item = O>, I: Clone, CG: Fn() -> C,

counted_separated without a separator.

Please read the notes in the documentation for this type.

Source

pub fn repeat<C, R: RangeLike, CG>( self, range: R, collection_generator: CG, ) -> Parser<impl ParserImpl<I, Output = C, Error = E>, I>
where C: Collection<Item = O>, I: Clone, CG: Fn() -> C,

separated without a separator.

Please read the notes in the documentation for this type.

Source

pub fn const_repeat<C, CG>( self, n: usize, collection_generator: CG, ) -> Parser<impl ParserImpl<I, Output = C, Error = E>, I>
where C: Collection<Item = O>, I: Clone, CG: Fn() -> C,

const_separated without a separator.

Please read the notes in the documentation for this type.

Source

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.

Source

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.

Source

pub fn maybe( self, ) -> Parser<impl ParserImpl<I, Output = Option<O>, Error = E>, I>
where I: Clone,

This returns a parser which attempts using this parser, wrapping the result in Some. If this parser fails, None is returned and no input is consumed.

Source

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?
examples/lisp.rs (line 86)
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    }
Source

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.

Source

pub fn map_range_and_out<O2, F2>( self, f: F2, ) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>
where F2: Fn((&I, &I), O) -> O2, I: Clone,

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.

Source

pub fn map_parser<O2, F2, F3>( self, f: F2, ) -> Parser<impl ParserImpl<I, Output = O2, Error = E>, I>
where F2: Fn(O) -> Parser<F3, I>, F3: ParserImpl<I, Output = O2, Error = E>,

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.

Source

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.

Source

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?
examples/lisp.rs (line 53)
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}
Source

pub fn parse(&self, input: I) -> Result<O, E>
where I: HasEof, E: EofError<I>,

Parses the whole input. Should this parser not consume it, an approriate error is returned.

Examples found in repository?
examples/lisp.rs (line 122)
121pub fn parse(i: &str) -> Result<Value, ParserError> {
122    (cf::f(parse_partial) >> -sp::ws(..)).parse(ParserInput::new(i))
123}

Trait Implementations§

Source§

impl<F, I> BitOr<()> for Parser<F, I>
where F: ParserImpl<I>, I: Clone,

Source§

type Output = Parser<MapLeft<CountedSeparated<fn() -> Option<<F as ParserImpl<I>>::Output>, RangeInclusive<usize>, F, Epsilon<<F as ParserImpl<I>>::Error>>>, I>

The resulting type after applying the | operator.
Source§

fn bitor(self, _: ()) -> Self::Output

Performs the | operation. Read more
Source§

impl<F1, F2, I> BitOr<Parser<F2, I>> for Parser<F1, I>
where F1: ParserImpl<I>, F2: ParserImpl<I, Output = F1::Output, Error = F1::Error>, I: Clone, F1::Error: AltError<I>,

Source§

type Output = Parser<Or<F1, F2>, I>

The resulting type after applying the | operator.
Source§

fn bitor(self, or: Parser<F2, I>) -> Self::Output

Performs the | operation. Read more
Source§

impl<F1, F2, I> Div<Parser<F2, I>> for Parser<F1, I>

Source§

type Output = ElementSeparator<F1, F2, I>

The resulting type after applying the / operator.
Source§

fn div(self, separator: Parser<F2, I>) -> Self::Output

Performs the / operation. Read more
Source§

impl<F, I, CG> Mul<CG> for Parser<F, I>

Source§

type Output = WithCollectionGenerator<Parser<F, I>, CG>

The resulting type after applying the * operator.
Source§

fn mul(self, cg: CG) -> Self::Output

Performs the * operation. Read more
Source§

impl<F, I> Neg for Parser<F, I>

Source§

type Output = Ignored<F, I>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Ignored<F, I>

Performs the unary - operation. Read more
Source§

impl<F1, F2, I, O> Shr<F2> for Parser<F1, I>
where F1: ParserImpl<I>, F2: Fn(F1::Output) -> O,

Source§

type Output = Parser<Map<F1, F2>, I>

The resulting type after applying the >> operator.
Source§

fn shr(self, map: F2) -> Self::Output

Performs the >> operation. Read more
Source§

impl<F1, F2, I> Shr<Ignored<F2, I>> for Parser<F1, I>
where F1: ParserImpl<I>, F2: ParserImpl<I, Error = F1::Error>,

Source§

type Output = Parser<MapLeft<Then<F1, F2>>, I>

The resulting type after applying the >> operator.
Source§

fn shr(self, next: Ignored<F2, I>) -> Self::Output

Performs the >> operation. Read more
Source§

impl<F1, F2, I, O> Shr<MapResult<F2>> for Parser<F1, I>
where F1: ParserImpl<I>, F2: Fn(F1::Output) -> Result<O, F1::Error>,

Source§

type Output = Parser<MapResult<F1, F2>, I>

The resulting type after applying the >> operator.
Source§

fn shr(self, map: MapResult<F2>) -> Self::Output

Performs the >> operation. Read more
Source§

impl<F1, F2, I> Shr<Parser<F2, I>> for Ignored<F1, I>
where F1: ParserImpl<I>, F2: ParserImpl<I, Error = F1::Error>,

Source§

type Output = Parser<MapRight<Then<F1, F2>>, I>

The resulting type after applying the >> operator.
Source§

fn shr(self, next: Parser<F2, I>) -> Self::Output

Performs the >> operation. Read more
Source§

impl<F1, F2, I> Shr<Parser<F2, I>> for Parser<F1, I>
where F1: ParserImpl<I>, F2: ParserImpl<I, Error = F1::Error>,

Source§

type Output = Parser<Then<F1, F2>, I>

The resulting type after applying the >> operator.
Source§

fn shr(self, next: Parser<F2, I>) -> Self::Output

Performs the >> operation. Read more

Auto Trait Implementations§

§

impl<F, I> Freeze for Parser<F, I>
where F: Freeze,

§

impl<F, I> RefUnwindSafe for Parser<F, I>
where F: RefUnwindSafe,

§

impl<F, I> Send for Parser<F, I>
where F: Send,

§

impl<F, I> Sync for Parser<F, I>
where F: Sync,

§

impl<F, I> Unpin for Parser<F, I>
where F: Unpin,

§

impl<F, I> UnwindSafe for Parser<F, I>
where F: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<I, P, T> Tag<Span<I, P>> for T
where I: Clone, P: Position<I>, T: Tag<I> + ?Sized,

Source§

type Output = <T as Tag<I>>::Output

Source§

fn parse_tag( &self, inp: Span<I, P>, ) -> Option<(<T as Tag<Span<I, P>>>::Output, Span<I, P>)>

The return type is reversed, since the tag is the beginning of the input.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.