[][src]Struct wast::parser::Parser

pub struct Parser<'a> { /* fields omitted */ }

An in-progress parser for the tokens of a WebAssembly text file.

A Parser is argument to the Parse trait and is now the input stream is interacted with to parse new items. Cloning Parser or copying a parser refers to the same stream of tokens to parse, you cannot clone a Parser and clone two items.

For more information about a Parser see its methods.

Methods

impl<'a> Parser<'a>[src]

pub fn is_empty(self) -> bool[src]

Returns whether there are no more Token tokens to parse from this Parser.

This indicates that either we've reached the end of the input, or we're a sub-Parser inside of a parenthesized expression and we've hit the ) token.

Note that if false is returned there may be more comments. Comments and whitespace are not considered for whether this parser is empty.

pub fn parse<T: Parse<'a>>(self) -> Result<T>[src]

Parses a T from this Parser.

This method has a trivial definition (it simply calls T::parse) but is here for syntactic purposes. This is what you'll call 99% of the time in a Parse implementation in order to parse sub-items.

Typically you always want to use ? with the result of this method, you should not handle errors and decide what else to parse. To handle branches in parsing, ue Parser::peek.

Examples

A good example of using parse is to see how the TableType type is parsed in this crate. A TableType is defined in the official specification as tabletype and is defined as:

tabletype ::= lim:limits et:elemtype

so to parse a TableType we recursively need to parse a Limits and a TableElemType

struct TableType {
    limits: Limits,
    elem: TableElemType,
}

impl<'a> Parse<'a> for TableType {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        // parse the `lim` then `et` in sequence
        Ok(TableType {
            limits: parser.parse()?,
            elem: parser.parse()?,
        })
    }
}

pub fn peek<T: Peek>(self) -> bool[src]

Performs a cheap test to see whether the current token in this stream is T.

This method can be used to efficiently determine what next to parse. The Peek trait is defined for types which can be used to test if they're the next item in the input stream.

Nothing is actually parsed in this method, nor does this mutate the state of this Parser. Instead, this simply performs a check.

This method is frequently combined with the Parser::lookahead1 method to automatically produce nice error messages if some tokens aren't found.

Examples

For an example of using the peek method let's take a look at parsing the Limits type. This is defined in the official spec as:

limits ::= n:u32
         | n:u32 m:u32

which means that it's either one u32 token or two, so we need to know whether to consume two tokens or one:

struct Limits {
    min: u32,
    max: Option<u32>,
}

impl<'a> Parse<'a> for Limits {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        // Always parse the first number...
        let min = parser.parse()?;

        // ... and then test if there's a second number before parsing
        let max = if parser.peek::<u32>() {
            Some(parser.parse()?)
        } else {
            None
        };

        Ok(Limits { min, max })
    }
}

pub fn peek2<T: Peek>(self) -> bool[src]

Same as the Parser::peek method, except checks the next token, not the current token.

pub fn lookahead1(self) -> Lookahead1<'a>[src]

A helper structure to perform a sequence of peek operations and if they all fail produce a nice error message.

This method purely exists for conveniently producing error messages and provides no functionality that Parser::peek doesn't already give. The Lookahead1 structure has one main method Lookahead1::peek, which is the same method as Parser::peek. The difference is that the Lookahead1::error method needs no arguments.

Examples

Let's look at the parsing of Index. This type is either a u32 or an Id and is used in name resolution primarily. The official grammar for an index is:

idx ::= x:u32
      | v:id

Which is to say that an index is either a u32 or an Id. When parsing an Index we can do:

enum Index<'a> {
    Num(u32),
    Id(Id<'a>),
}

impl<'a> Parse<'a> for Index<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        let mut l = parser.lookahead1();
        if l.peek::<Id>() {
            Ok(Index::Id(parser.parse()?))
        } else if l.peek::<u32>() {
            Ok(Index::Num(parser.parse()?))
        } else {
            // produces error message of `expected identifier or u32`
            Err(l.error())
        }
    }
}

pub fn parens<T>(self, f: impl FnOnce(Parser<'a>) -> Result<T>) -> Result<T>[src]

Parsea an item surrounded by parentheses.

WebAssembly's text format is all based on s-expressions, so naturally you're going to want to parse a lot of parenthesized things! As noted in the documentation of Parse you typically don't parse your own surrounding ( and ) tokens, but the parser above you parsed them for you. This is method method the parser above you uses.

This method will parse a ( token, and then call f on a sub-parser which when finished asserts that a ) token is the next token. This requires that f consumes all tokens leading up to the paired ).

Usage will often simply be parser.parens(|p| p.parse())? to automatically parse a type within parentheses, but you can, as always, go crazy and do whatever you'd like too.

Examples

A good example of this is to see how a Module is parsed. This isn't the exact definition, but it's close enough!

struct Module<'a> {
    fields: Vec<ModuleField<'a>>,
}

impl<'a> Parse<'a> for Module<'a> {
    fn parse(parser: Parser<'a>) -> Result<Self> {
        // Modules start out with a `module` keyword
        parser.parse::<kw::module>()?;

        // And then everything else is `(field ...)`, so while we've got
        // items left we continuously parse parenthesized items.
        let mut fields = Vec::new();
        while !parser.is_empty() {
            fields.push(parser.parens(|p| p.parse())?);
        }
        Ok(Module { fields })
    }
}

pub fn step<F, T>(self, f: F) -> Result<T> where
    F: FnOnce(Cursor<'a>) -> Result<(T, Cursor<'a>)>, 
[src]

A low-level parsing method you probably won't use.

This is used to implement parsing of the most primitive types in the ast module. You probably don't want to use this, but probably want to use something like Parser::parse or Parser::parens.

pub fn error(self, msg: impl Display) -> Error[src]

Creates an error whose line/column information is pointing at the current token.

This is used to produce human-readable error messages which point to the right location in the input stream, and the msg here is arbitrary text used to associate with the error and indicate why it was generated.

pub fn cur_span(&self) -> Span[src]

Returns the span of the current token

Trait Implementations

impl<'a> Clone for Parser<'a>[src]

impl<'a> Copy for Parser<'a>[src]

Auto Trait Implementations

impl<'a> !Send for Parser<'a>

impl<'a> !Sync for Parser<'a>

impl<'a> Unpin for Parser<'a>

impl<'a> !UnwindSafe for Parser<'a>

impl<'a> !RefUnwindSafe for Parser<'a>

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = !

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]