[][src]Trait autumn::combinators::ParserExt

pub trait ParserExt<T, E>: Parser<T, E> + Sized {
    fn or<P: Parser<T, E>>(self, other: P) -> Or<Self, P, E> { ... }
fn map<V, F: Fn(T) -> V>(self, map: F) -> Map<Self, F, T, E> { ... }
fn and_then<V, Q: Parser<V, E>, F: Fn(T) -> Q>(
        self,
        map: F
    ) -> AndThen<Self, F, T, E> { ... }
fn fold<P: Parser<T, E>, F: Fn(T) -> P>(self, fold: F) -> Fold<Self, F, E> { ... }
fn on_failure<P: Parser<T, E>>(self, other: P) -> OnFailure<Self, P, E> { ... }
fn on_none<P: Parser<T, E>>(self, other: P) -> OnNone<Self, P, E> { ... }
fn drop<V, P: Parser<V, E>>(self, other: P) -> Drop<Self, P, V, E> { ... }
fn maybe_drop<V, P: Parser<V, E>>(
        self,
        other: P
    ) -> MaybeDrop<Self, P, V, E> { ... }
fn skip<V, P: Parser<V, E>>(self, keep: P) -> Skip<Self, P, T, E> { ... }
fn condition<F: Fn(&T) -> bool>(self, condition: F) -> Condition<Self, F, E> { ... }
fn end(self) -> End<Self, E> { ... }
fn catch(self) -> Catch<Self, E> { ... }
fn meta(self) -> MetaMap<Self, E> { ... }
fn to_list(self) -> ListMap<Self, E> { ... }
fn delimited_by<D, P: Parser<D, E>, R: RangeBounds<usize>>(
        self,
        delimiter: P,
        repetitions: R
    ) -> DelimitedBy<Self, P, D, R, E> { ... }
fn strictly_delimited_by<D, P: Parser<D, E>, R: RangeBounds<usize>>(
        self,
        delimiter: P,
        repetitions: R
    ) -> StrictlyDelimitedBy<Self, P, D, R, E> { ... }
fn surrounded_by<O: Clone, C: Clone, OP: Parser<O, E>, CP: Parser<C, E>>(
        self,
        open: OP,
        close: CP
    ) -> SurroundedBy<Self, OP, CP, O, C, E> { ... }
fn pair<B, P: Parser<B, E>>(self, other: P) -> Pair<Self, P, E> { ... }
fn space_after(self) -> SpaceAfter<Self, E> { ... }
fn maybe_space_after(self) -> MaybeSpaceAfter<Self, E> { ... }
fn space_before(self) -> SpaceBefore<Self, E> { ... }
fn maybe_space_before(self) -> MaybeSpaceBefore<Self, E> { ... }
fn space_around(self) -> SpaceAround<Self, E> { ... }
fn maybe_space_around(self) -> MaybeSpaceAround<Self, E> { ... } }

Combinators that can be used on all parsers

Provided methods

fn or<P: Parser<T, E>>(self, other: P) -> Or<Self, P, E>

Evaluate two alternative parsers producing all successful parses from both

fn alpha_or_beta() -> impl Parser<String> {
    "alpha".or("beta").copy_string()
}

fn map<V, F: Fn(T) -> V>(self, map: F) -> Map<Self, F, T, E>

Map the output of a parser to a new value and type

use std::str::FromStr;
fn integer() -> impl Parser<i32> {
    digit.multiple().copy_string().map(|i| FromStr::from_str(&i).unwrap())
}

fn and_then<V, Q: Parser<V, E>, F: Fn(T) -> Q>(
    self,
    map: F
) -> AndThen<Self, F, T, E>

Apply an additional parser dependant on the result of the preceding parser

use std::str::FromStr;
enum Token {
    Identifier(String),
    Literal(i32),
}
use Token::*;

fn identifier() -> impl Parser<String> {
    alphabetic.and(alphanumeric.multiple().maybe()).copy_string()
}

fn literal() -> impl Parser<i32> {
    "-".maybe()
        .and(digit.multiple())
        .copy_string()
        .map(|i| FromStr::from_str(&i).unwrap())
}

fn tagged_token() -> impl Parser<Token> {
    "identifier"
        .or("literal")
        .drop(space)
        .copy_string()
        .and_then(|parsed| {
            match parsed.as_str() {
                "identifier" => identifier().map(Identifier).boxed(),
                "literal" => literal().map(Literal).boxed(),
                _ => unreachable!()
            }
        })
}

fn fold<P: Parser<T, E>, F: Fn(T) -> P>(self, fold: F) -> Fold<Self, F, E>

Repeatedly apply a parser using it to extend the previous results of the parse

This allows for a form of 'left recursion' where a parser rule includes itself as its first parser.

fn identifier() -> impl Parser<String> {
    alphabetic.and(alphanumeric.repeated(..)).copy_string()
}

fn concat() -> impl Parser<String> {
    identifier()
        .fold(|left| {
            "##".maybe_space_around()
                .skip(identifier())
                .map(move |right| {
                    let mut left = left.clone();
                    left.push_str(&right);
                    left
                })
        })
}

fn on_failure<P: Parser<T, E>>(self, other: P) -> OnFailure<Self, P, E>

Apply an alternative parser if the preceding parser produces errors or no successful parses

fn failing_parser() -> impl Parser<String, &'static str> {
    "hello"
        .and("world")
        .copy_string()
        .on_none(error(String::new(), "Not hello world"))
        .on_failure(error(String::new(), "Caught error"))
}

fn on_none<P: Parser<T, E>>(self, other: P) -> OnNone<Self, P, E>

Apply an alternative parser if the preceding parser produces no successful parses

fn parse_handle_none() -> impl Parser<String, &'static str> {
    "hello"
        .and("world")
        .copy_string()
        .on_none(error(String::new(), "Not hello world"))
}

fn drop<V, P: Parser<V, E>>(self, other: P) -> Drop<Self, P, V, E>

Apply an additional parser and discard the result

fn drop_trailing_whitespace() -> impl Parser<String> {
    "hello".drop(space).copy_string()
}

fn maybe_drop<V, P: Parser<V, E>>(self, other: P) -> MaybeDrop<Self, P, V, E>

Apply an additional parser and discard any result

fn drop_trailing_whitespace() -> impl Parser<String> {
    "hello".maybe_drop(space).copy_string()
}

fn skip<V, P: Parser<V, E>>(self, keep: P) -> Skip<Self, P, T, E>

Apply an additional parser and take its output instead

fn drop_leading_whitespace() -> impl Parser<String> {
    space.skip("hello").copy_string()
}

fn condition<F: Fn(&T) -> bool>(self, condition: F) -> Condition<Self, F, E>

Only parse successfully if the output of the parser satisfies a given condition

use std::str::FromStr;
fn foutry_two() -> impl Parser<i32> {
    digit
        .multiple()
        .copy_string()
        .map(|i| FromStr::from_str(&i).unwrap())
        .condition(|i| *i == 42)
}

fn end(self) -> End<Self, E>

Only parse successfully if there is no text remaining in the input after a parse

fn single_line() -> impl Parser<String> {
    any_character
        .str_condition(|s| !s.chars().any(|c| c == '\n'))
        .drop("\n")
        .copy_string()
        .end()
}

fn catch(self) -> Catch<Self, E>

Transform all exceptions in the result into errors, moving the start of the associated range to the start of the given parser.

See exceptions.

fn meta(self) -> MetaMap<Self, E>

Wrap the output of a parser with the location of the input parsed

fn identifier_location() -> impl Parser<Meta<String, Span>> {
    alphabetic
        .and(alphanumeric.multiple().maybe())
        .copy_string()
        .meta()
}

fn to_list(self) -> ListMap<Self, E>

Wrap the value of a parser in a list

use std::str::FromStr;
fn parse_integers() -> impl Parser<List<i32>> {
    "-".maybe()
        .and(digit.multiple())
        .copy_string()
        .map(|s| FromStr::from_str(&s).unwrap())
        .to_list()
        .multiple()
}

fn delimited_by<D, P: Parser<D, E>, R: RangeBounds<usize>>(
    self,
    delimiter: P,
    repetitions: R
) -> DelimitedBy<Self, P, D, R, E>

Repeat the parser a given number of times with the provided delimeter with an optional trailing delimeter

use std::str::FromStr;
fn integer() -> impl Parser<i32> {
    "-".maybe()
        .and(digit.multiple())
        .copy_string()
        .map(|s| FromStr::from_str(&s).unwrap())
}

fn integer_list() -> impl Parser<List<i32>> {
    integer()
        .maybe_space_after()
        .delimited_by(",".maybe_space_after(), ..)
        .surrounded_by("[".maybe_space_after(), "]")
}

fn strictly_delimited_by<D, P: Parser<D, E>, R: RangeBounds<usize>>(
    self,
    delimiter: P,
    repetitions: R
) -> StrictlyDelimitedBy<Self, P, D, R, E>

Repeat the parser a given number of times with the provided delimeter

use std::str::FromStr;
fn integer() -> impl Parser<i32> {
    "-".maybe()
        .and(digit.multiple())
        .copy_string()
        .map(|s| FromStr::from_str(&s).unwrap())
}

fn integer_list() -> impl Parser<List<i32>> {
    integer()
        .maybe_space_after()
        .strictly_delimited_by(",".maybe_space_after(), ..)
        .surrounded_by("[".maybe_space_after(), "]")
}

fn surrounded_by<O: Clone, C: Clone, OP: Parser<O, E>, CP: Parser<C, E>>(
    self,
    open: OP,
    close: CP
) -> SurroundedBy<Self, OP, CP, O, C, E>

Enclose the parser in the given open and close delimeters

use std::str::FromStr;
fn integer() -> impl Parser<i32> {
    "-".maybe()
        .and(digit.multiple())
        .copy_string()
        .map(|s| FromStr::from_str(&s).unwrap())
}

fn integer_list() -> impl Parser<List<i32>> {
    integer()
        .maybe_space_after()
        .strictly_delimited_by(",".maybe_space_after(), ..)
        .surrounded_by("[".maybe_space_after(), "]")
}

fn pair<B, P: Parser<B, E>>(self, other: P) -> Pair<Self, P, E>

Parse two parsers and collect them in a tuple

use std::collections::HashSet;
fn operator<O: Clone, A: Clone, B: Clone>(
    operator: impl Parser<O>,
    left: impl Parser<A>,
    right: impl Parser<B>,
) -> impl Parser<(A, B)> {
    left.drop(operator.maybe_space_around()).pair(right)
}

fn space_after(self) -> SpaceAfter<Self, E>

Ignore the space that always appears after the parser

use std::collections::HashSet;
fn item() -> impl Parser<String> {
    alphanumeric.multiple().copy_string()
}

fn set_decl() -> impl Parser<HashSet<String>> {
    item()
        .delimited_by(space, ..)
        .surrounded_by(
            "set".space_after().drop("{".maybe_space_after()),
            "}"
        )
        .collect()
}

fn maybe_space_after(self) -> MaybeSpaceAfter<Self, E>

Ignore the space that might appear after the parser

use std::collections::HashSet;
fn item() -> impl Parser<String> {
    alphanumeric.multiple().copy_string()
}

fn set_decl() -> impl Parser<HashSet<String>> {
    item()
        .delimited_by(space, ..)
        .surrounded_by(
            "set".maybe_space_after().drop("{".maybe_space_after()),
            "}"
        )
        .collect()
}

fn space_before(self) -> SpaceBefore<Self, E>

Ignore the space that always appears before the parser

fn maybe_space_before(self) -> MaybeSpaceBefore<Self, E>

Ignore the space that might appear before the parser

fn space_around(self) -> SpaceAround<Self, E>

Ignore the space that always appears before and after the parser

fn maybe_space_around(self) -> MaybeSpaceAround<Self, E>

Ignore the space that might appear before or after the parser

use std::collections::HashSet;
fn operator<O: Clone, A: Clone, B: Clone>(
    left: impl Parser<A>,
    operator: impl Parser<O>,
    right: impl Parser<B>,
) -> impl Parser<(A, B)> {
    left.drop(operator.maybe_space_around()).pair(right)
}
Loading content...

Implementors

impl<T, E, P: Parser<T, E>> ParserExt<T, E> for P[src]

Loading content...