Skip to main content

PrattParser

Struct PrattParser 

Source
pub struct PrattParser<L: Language, T: Pratt<L>> { /* private fields */ }
Expand description

A Pratt parser implementation.

§Examples

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
enum Token { Number, Plus, Minus, Star, Slash, Eof }
impl TokenType for Token {
    const END_OF_STREAM: Self = Token::Eof;
    type Role = UniversalTokenRole;
    fn role(&self) -> Self::Role { UniversalTokenRole::None }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
enum Element { Expr, Number, Plus, Minus, Star, Slash }
impl ElementType for Element {
    type Role = UniversalElementRole;
    fn role(&self) -> Self::Role { UniversalElementRole::None }
}
impl From<Token> for Element {
    fn from(t: Token) -> Self {
        match t {
            Token::Number => Element::Number,
            Token::Plus => Element::Plus,
            Token::Minus => Element::Minus,
            Token::Star => Element::Star,
            Token::Slash => Element::Slash,
            Token::Eof => unreachable!(),
        }
    }
}

#[derive(Clone, Copy)]
struct Lang;
impl Language for Lang {
    const NAME: &'static str = "test";
    type TokenType = Token;
    type ElementType = Element;
    type TypedRoot = ();
}

struct ExprParser;
impl Pratt<Lang> for ExprParser {
    fn primary<'a, S: oak_core::Source + ?Sized>(&self, state: &mut ParserState<'a, Lang, S>) -> &'a oak_core::GreenNode<'a, Lang> {
        let cp = state.checkpoint();
        state.bump(); // bump number
        state.finish_at(cp, Element::Number)
    }

    fn infix<'a, S: oak_core::Source + ?Sized>(&self, state: &mut ParserState<'a, Lang, S>, left: &'a oak_core::GreenNode<'a, Lang>, min_prec: u8) -> Option<&'a oak_core::GreenNode<'a, Lang>> {
        let kind = state.peek_kind()?;
        let (prec, assoc) = match kind {
            Token::Plus | Token::Minus => (1, oak_core::Associativity::Left),
            Token::Star | Token::Slash => (2, oak_core::Associativity::Left),
            _ => return None,
        }
        if prec < min_prec { return None }
        Some(binary(state, left, kind, prec, assoc, Element::Expr, |s, p| self.parse_expr(s, p)))
    }
}

impl ExprParser {
    fn parse_expr<'a, S: oak_core::Source + ?Sized>(&self, state: &mut ParserState<'a, Lang, S>, min_prec: u8) -> &'a oak_core::GreenNode<'a, Lang> {
        PrattParser::new(ExprParser).parse_expr(state, min_prec)
    }
}

Implementations§

Source§

impl<L: Language, T: Pratt<L>> PrattParser<L, T>

Source

pub const fn new(spec: T) -> Self

Creates a new Pratt parser with the given specification.

Source

pub fn parse_expr<'a, S: Source + ?Sized>( &self, state: &mut ParserState<'a, L, S>, min_precedence: u8, ) -> &'a GreenNode<'a, L>

Parses an expression with the given minimum precedence.

Source

pub fn parse<'a, S: Source + ?Sized>( state: &mut ParserState<'a, L, S>, min_precedence: u8, spec: &T, ) -> &'a GreenNode<'a, L>

Static version of parse_expr that takes a specification reference.

Auto Trait Implementations§

§

impl<L, T> Freeze for PrattParser<L, T>
where T: Freeze,

§

impl<L, T> RefUnwindSafe for PrattParser<L, T>

§

impl<L, T> Send for PrattParser<L, T>
where T: Send,

§

impl<L, T> Sync for PrattParser<L, T>
where T: Sync,

§

impl<L, T> Unpin for PrattParser<L, T>
where T: Unpin, L: Unpin,

§

impl<L, T> UnsafeUnpin for PrattParser<L, T>
where T: UnsafeUnpin,

§

impl<L, T> UnwindSafe for PrattParser<L, T>
where T: UnwindSafe, L: 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.