Expression

Struct Expression 

Source
pub struct Expression<I, O, ParseOperand, Pre, Post, Pix, E>
where I: Stream + StreamIsPartial, ParseOperand: Parser<I, O, E>, E: ParserError<I>,
{ precedence_level: i64, parse_operand: ParseOperand, parse_prefix: Pre, parse_postfix: Post, parse_infix: Pix, i: PhantomData<I>, o: PhantomData<O>, e: PhantomData<E>, }
Expand description

A helper struct for expression().

Holds the configuration for the Pratt parser, including the operator and operand parsers. A precedence level can also be set, which is useful to disambiguate parse trees based on the parent operator’s precedence.

Implements Parser. When parsing an input, it applies the Pratt parser.

Fields§

§precedence_level: i64§parse_operand: ParseOperand§parse_prefix: Pre§parse_postfix: Post§parse_infix: Pix§i: PhantomData<I>§o: PhantomData<O>§e: PhantomData<E>

Implementations§

Source§

impl<I, O, ParseOperand, Pre, Post, Pix, E> Expression<I, O, ParseOperand, Pre, Post, Pix, E>
where ParseOperand: Parser<I, O, E>, I: Stream + StreamIsPartial, E: ParserError<I>,

Source

pub fn prefix<NewParsePrefix>( self, parser: NewParsePrefix, ) -> Expression<I, O, ParseOperand, NewParsePrefix, Post, Pix, E>
where NewParsePrefix: Parser<I, Prefix<I, O, E>, E>,

Sets the prefix operator parser.

The parser should parse the input to a Prefix, which contains the operator’s binding power and a fold function which applies the operator to its operands.

Source

pub fn postfix<NewParsePostfix>( self, parser: NewParsePostfix, ) -> Expression<I, O, ParseOperand, Pre, NewParsePostfix, Pix, E>
where NewParsePostfix: Parser<I, Postfix<I, O, E>, E>,

Sets the prefix operator parser.

The parser should parse the input to a Postfix, which contains the operator’s binding power and a fold function which applies the operator to its operands.

Source

pub fn infix<NewParseInfix>( self, parser: NewParseInfix, ) -> Expression<I, O, ParseOperand, Pre, Post, NewParseInfix, E>
where NewParseInfix: Parser<I, Infix<I, O, E>, E>,

Sets the prefix operator parser.

The parser should parse the input to a Infix, which contains the operator’s binding power and a fold function which applies the operator to its operands.

Source

pub fn current_precedence_level( self, level: i64, ) -> Expression<I, O, ParseOperand, Pre, Post, Pix, E>

Sets the precedence level for the current instance of the parser.

It defaults to 0, which is traditionally treated as the “lowest” possible precedence when parsing an expression.

This is useful to disambiguate grammars based on the parent operator’s precedence. This comes up primarily when parsing recursive expressions.

The parsing machinery underpinning Expression assumes that a “more tightly binding” operator is numerically large, while a “more loosely binding” operator is numerically small. For example, 13 is a higher precedence level than 1 because 13 > 1.

Other ways of describing this relationship:

  • 13 has a higher precedence compared to 1
  • 13 has a higher binding power compared to 1

Note: Binding power and precedence both refer to the same concept and may be used interchangeably.

§Motivation

If you don’t understand why this is useful to have, this section tries to explain in more detail.

The [C-style Expressions][crate::_topic::arithmetic#c-style-expression] example has source code for parsing the expression described below, and can provide a clearer usage example.

Consider the following expression in the C language:

int x = (1 == 1 ? 0 : 1, -123); // <-- let's parse this
printf("%d\n", x); // -123

Let’s look at the right-hand side of the expression on the first line, and replace some of the sub-expressions with symbols:

(1 == 1 ? 0 : 1, -123) // rhs
(a      ? b : c, d  )  // symbolic
(a ? b : c, d)         // remove whitespace
(, (? a b c) d)        // prefix notation

Written symbolically:

  • a is the condition, like 1 == 1
  • b is the value when the condition is true
  • c is the value when the condition is false
  • d is a secondary expression unrelated to the ternary

In prefix notation, it’s easier to see the specific operators and what they bind to:

  • COMMA (,) binds to (? a b c) and d
  • TERNARY (?) binds to a, b, and c
§Parsing c and d

Let’s focus on parsing the sub-expressions c and d, as that motivates why a parser precedence level is necessary.

To parse c, we would really like to re-use the parser produced by expression(), because c is really any valid expression that can be parsed by expression() already.

However, we can’t re-use the parser naively. When parsing c, we need to “escape” from the inner parser when encountering the comma separating c from d.

The reason we have to “escape” is because of how operator precedence is defined in the C language: the comma operator has the lowest precedence among all the operators. When we’re parsing c, we’re in the context of the ternary operator. We don’t want to parse any valid expression! Just what the ternary operator captures.

That’s where the precedence level comes in: you specify the minimum precedence this parser is willing to accept. If you come across an expression in the top-level with a lower binding power than the starting precedence, you know to stop parsing.

The parsing machinery inside of Expression handles most of this for you, but it can’t determine what the precedence level should be for a given expression. That’s a language-specific detail, and it depends on what you want to parse.

Trait Implementations§

Source§

impl<I, O, Pop, Pre, Post, Pix, E> Parser<I, O, E> for Expression<I, O, Pop, Pre, Post, Pix, E>
where I: Stream + StreamIsPartial, Pop: Parser<I, O, E>, Pix: Parser<I, Infix<I, O, E>, E>, Pre: Parser<I, Prefix<I, O, E>, E>, Post: Parser<I, Postfix<I, O, E>, E>, E: ParserError<I>,

Source§

fn parse_next(&mut self, input: &mut I) -> Result<O, E>

Take tokens from the Stream, turning it into the output Read more
Source§

fn parse( &mut self, input: I, ) -> Result<O, ParseError<I, <E as ParserError<I>>::Inner>>
where Self: Sized, I: Stream + StreamIsPartial, E: ParserError<I>, <E as ParserError<I>>::Inner: ParserError<I>,

Parse all of input, generating O from it Read more
Source§

fn parse_peek(&mut self, input: I) -> Result<(I, O), E>

Take tokens from the Stream, turning it into the output Read more
Source§

fn by_ref(&mut self) -> ByRef<'_, Self, I, O, E>
where Self: Sized,

Treat &mut Self as a parser Read more
Source§

fn value<O2>(self, val: O2) -> Value<Self, I, O, O2, E>
where Self: Sized, O2: Clone,

Produce the provided value Read more
Source§

fn default_value<O2>(self) -> DefaultValue<Self, I, O, O2, E>
where Self: Sized, O2: Default,

Produce a type’s default value Read more
Source§

fn void(self) -> Void<Self, I, O, E>
where Self: Sized,

Discards the output of the Parser Read more
Source§

fn output_into<O2>(self) -> OutputInto<Self, I, O, O2, E>
where Self: Sized, O: Into<O2>,

Convert the parser’s output to another type using std::convert::From Read more
Source§

fn take(self) -> Take<Self, I, O, E>
where Self: Sized, I: Stream,

Produce the consumed input as produced value. Read more
Source§

fn with_taken(self) -> WithTaken<Self, I, O, E>
where Self: Sized, I: Stream,

Produce the consumed input with the output Read more
Source§

fn span(self) -> Span<Self, I, O, E>
where Self: Sized, I: Stream + Location,

Produce the location of the consumed input as produced value. Read more
Source§

fn with_span(self) -> WithSpan<Self, I, O, E>
where Self: Sized, I: Stream + Location,

Produce the location of consumed input with the output Read more
Source§

fn map<G, O2>(self, map: G) -> Map<Self, G, I, O, O2, E>
where G: FnMut(O) -> O2, Self: Sized,

Maps a function over the output of a parser Read more
Source§

fn try_map<G, O2, E2>(self, map: G) -> TryMap<Self, G, I, O, O2, E, E2>
where Self: Sized, G: FnMut(O) -> Result<O2, E2>, I: Stream, E: FromExternalError<I, E2> + ParserError<I>,

Applies a function returning a Result over the output of a parser. Read more
Source§

fn verify_map<G, O2>(self, map: G) -> VerifyMap<Self, G, I, O, O2, E>
where Self: Sized, G: FnMut(O) -> Option<O2>, I: Stream, E: ParserError<I>,

Source§

fn flat_map<G, H, O2>(self, map: G) -> FlatMap<Self, G, H, I, O, O2, E>
where Self: Sized, G: FnMut(O) -> H, H: Parser<I, O2, E>,

Creates a parser from the output of this one Read more
Source§

fn and_then<G, O2>(self, inner: G) -> AndThen<Self, G, I, O, O2, E>
where Self: Sized, G: Parser<O, O2, E>, O: StreamIsPartial, I: Stream,

Applies a second parser over the output of the first one Read more
Source§

fn parse_to<O2>(self) -> ParseTo<Self, I, O, O2, E>
where Self: Sized, I: Stream, O: ParseSlice<O2>, E: ParserError<I>,

Apply std::str::FromStr to the output of the parser Read more
Source§

fn verify<G, O2>(self, filter: G) -> Verify<Self, G, I, O, O2, E>
where Self: Sized, G: FnMut(&O2) -> bool, I: Stream, O: Borrow<O2>, O2: ?Sized, E: ParserError<I>,

Returns the output of the child parser if it satisfies a verification function. Read more
Source§

fn context<C>(self, context: C) -> Context<Self, I, O, E, C>
where Self: Sized, I: Stream, E: AddContext<I, C> + ParserError<I>, C: Clone + Debug,

If parsing fails, add context to the error Read more
Source§

fn context_with<F, C, FI>( self, context: F, ) -> ContextWith<Self, I, O, E, F, C, FI>
where Self: Sized, I: Stream, E: AddContext<I, C> + ParserError<I>, F: Fn() -> FI + Clone, C: Debug, FI: Iterator<Item = C>,

If parsing fails, dynamically add context to the error Read more
Source§

fn map_err<G, E2>(self, map: G) -> MapErr<Self, G, I, O, E, E2>
where G: FnMut(E) -> E2, Self: Sized,

Maps a function over the error of a parser Read more
Source§

fn complete_err(self) -> CompleteErr<Self, I, O, E>
where Self: Sized,

Source§

fn err_into<E2>(self) -> ErrInto<Self, I, O, E, E2>
where Self: Sized, E: Into<E2>,

Convert the parser’s error to another type using std::convert::From

Auto Trait Implementations§

§

impl<I, O, ParseOperand, Pre, Post, Pix, E> Freeze for Expression<I, O, ParseOperand, Pre, Post, Pix, E>
where ParseOperand: Freeze, Pre: Freeze, Post: Freeze, Pix: Freeze,

§

impl<I, O, ParseOperand, Pre, Post, Pix, E> RefUnwindSafe for Expression<I, O, ParseOperand, Pre, Post, Pix, E>

§

impl<I, O, ParseOperand, Pre, Post, Pix, E> Send for Expression<I, O, ParseOperand, Pre, Post, Pix, E>
where ParseOperand: Send, Pre: Send, Post: Send, Pix: Send, I: Send, O: Send, E: Send,

§

impl<I, O, ParseOperand, Pre, Post, Pix, E> Sync for Expression<I, O, ParseOperand, Pre, Post, Pix, E>
where ParseOperand: Sync, Pre: Sync, Post: Sync, Pix: Sync, I: Sync, O: Sync, E: Sync,

§

impl<I, O, ParseOperand, Pre, Post, Pix, E> Unpin for Expression<I, O, ParseOperand, Pre, Post, Pix, E>
where ParseOperand: Unpin, Pre: Unpin, Post: Unpin, Pix: Unpin, I: Unpin, O: Unpin, E: Unpin,

§

impl<I, O, ParseOperand, Pre, Post, Pix, E> UnwindSafe for Expression<I, O, ParseOperand, Pre, Post, Pix, E>
where ParseOperand: UnwindSafe, Pre: UnwindSafe, Post: UnwindSafe, Pix: UnwindSafe, I: UnwindSafe, O: UnwindSafe, E: 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<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.
Source§

impl<I, O, E, P> ModalParser<I, O, E> for P
where P: Parser<I, O, ErrMode<E>>,