[−][src]Struct wast::parser::Parser
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]
F: FnOnce(Cursor<'a>) -> Result<(T, Cursor<'a>)>,
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
Auto Trait Implementations
impl<'a> !RefUnwindSafe for Parser<'a>
impl<'a> !Send for Parser<'a>
impl<'a> !Sync for Parser<'a>
impl<'a> Unpin for Parser<'a>
impl<'a> !UnwindSafe for Parser<'a>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,