# Struct pest::pratt_parser::PrattParser

source · [−]

    pub struct PrattParser<R: RuleType> { /* private fields */ }

Expand description

Struct containing operators and precedences, which can perform Pratt parsing on primary, prefix, postfix and infix expressions over `Pairs`. The tokens in `Pairs` should alternate in the order: `prefix* ~ primary ~ postfix* ~ (infix ~ prefix* ~ primary ~ postfix*)*`

## Panics

Panics will occur when:

- `pairs` is empty
- The tokens in `pairs` does not alternate in the expected order.
- No `map_*` function is specified for a certain kind of operator encountered in `pairs`.

## Example

The following pest grammar defines a calculator which can be used for Pratt parsing.

    WHITESPACE   =  _{ " " | "\t" | NEWLINE }

    program      =   { SOI ~ expr ~ EOI }
      expr       =   { prefix* ~ primary ~ postfix* ~ (infix ~ prefix* ~ primary ~ postfix* )* }
        infix    =  _{ add | sub | mul | div | pow }
          add    =   { "+" } // Addition
          sub    =   { "-" } // Subtraction
          mul    =   { "*" } // Multiplication
          div    =   { "/" } // Division
          pow    =   { "^" } // Exponentiation
        prefix   =  _{ neg }
          neg    =   { "-" } // Negation
        postfix  =  _{ fac }
          fac    =   { "!" } // Factorial
        primary  =  _{ int | "(" ~ expr ~ ")" }
          int    =  @{ (ASCII_NONZERO_DIGIT ~ ASCII_DIGIT+ | ASCII_DIGIT) }

Below is a `PrattParser` that is able to parse an `expr` in the above grammar. The order of precedence corresponds to the order in which `op` is called. Thus, `mul` will have higher precedence than `add`. Operators can also be chained with `|` to give them equal precedence.

    let pratt =
        PrattParser::new()
            .op(Op::infix(Rule::add, Assoc::Left) | Op::infix(Rule::sub, Assoc::Left))
            .op(Op::infix(Rule::mul, Assoc::Left) | Op::infix(Rule::div, Assoc::Left))
            .op(Op::infix(Rule::pow, Assoc::Right))
            .op(Op::postfix(Rule::fac))
            .op(Op::prefix(Rule::neg));

To parse an expression, call the `map_primary`, `map_prefix`, `map_postfix`, `map_infix` and `parse` methods as follows:

    fn parse_expr(pairs: Pairs<Rule>, pratt: &PrattParser<Rule>) -> i32 {
        pratt
            .map_primary(|primary| match primary.as_rule() {
                Rule::int  => primary.as_str().parse().unwrap(),
                Rule::expr => parse_expr(primary.into_inner(), pratt), // from "(" ~ expr ~ ")"
                _          => unreachable!(),
            })
            .map_prefix(|op, rhs| match op.as_rule() {
                Rule::neg  => -rhs,
                _          => unreachable!(),
            })
            .map_postfix(|lhs, op| match op.as_rule() {
                Rule::fac  => (1..lhs+1).product(),
                _          => unreachable!(),
            })
            .map_infix(|lhs, op, rhs| match op.as_rule() {
                Rule::add  => lhs + rhs,
                Rule::sub  => lhs - rhs,
                Rule::mul  => lhs * rhs,
                Rule::div  => lhs / rhs,
                Rule::pow  => (1..rhs+1).map(|_| lhs).product(),
                _          => unreachable!(),
            })
            .parse(pairs)
    }

Note that `map_prefix`, `map_postfix` and `map_infix` only need to be specified if the grammar contains the corresponding operators.

## Implementations

source

### impl<R: RuleType> PrattParser<R>

source

#### pub fn new() -> Self

Instantiate a new `PrattParser`.

source

#### pub fn op(self, op: Op<R>) -> Self

Add `op` to `PrattParser`.

source

#### pub fn map_primary<'pratt, 'i, X, T>(
&'pratt self,
primary: X
) -> PrattParserMap<'pratt, 'i, R, X, T> where
X: FnMut(Pair<'i, R>) -> T,
R: 'pratt,

Maps primary expressions with a closure `primary`.

## Trait Implementations

source

### impl<R: RuleType> Default for PrattParser<R>

source

#### fn default() -> Self

Returns the “default value” for a type. Read more

## Auto Trait Implementations

### impl<R> RefUnwindSafe for PrattParser<R> where
R: RefUnwindSafe,

### impl<R> Send for PrattParser<R> where
R: Send,

### impl<R> Sync for PrattParser<R> where
R: Sync,

### impl<R> Unpin for PrattParser<R>

### impl<R> UnwindSafe for PrattParser<R> where
R: RefUnwindSafe,

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

const: unstable · source

#### fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more

source

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

const: unstable · source

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

Mutably borrows from an owned value. Read more

source

### impl<T> From<T> for T

const: unstable · source

#### fn from(t: T) -> T

Returns the argument unchanged.

source

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

const: unstable · 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<T, U> TryFrom<U> for T where
U: Into<T>,

#### type Error = Infallible

The type returned in the event of a conversion error.

const: unstable · 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>,

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

The type returned in the event of a conversion error.

const: unstable · source

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

Performs the conversion.