Struct chumsky::stream::Stream

source ·
pub struct Stream<'a, I, S: Span, Iter: Iterator<Item = (I, S)> + ?Sized = dyn Iterator<Item = (I, S)> + 'a> { /* private fields */ }
Expand description

A type that represents a stream of input tokens. Unlike Iterator, this type supports backtracking and a few other features required by the crate.

Implementations§

Create a new stream from an iterator of (Token, Span) pairs. A span representing the end of input must also be provided.

There is no requirement that spans must map exactly to the position of inputs in the stream, but they should be non-overlapping and should appear in a monotonically-increasing order.

Eagerly evaluate the token stream, returning an iterator over the tokens in it (but without modifying the stream’s state so that it can still be used for parsing).

This is most useful when you wish to check the input of a parser during debugging.

Create a new Stream from an iterator of nested tokens and a function that flattens them.

It’s not uncommon for compilers to perform delimiter parsing during the lexing stage (Rust does this!). When this is done, the output of the lexing stage is usually a series of nested token trees. This functions allows you to easily flatten such token trees into a linear token stream so that they can be parsed (Chumsky currently only support parsing linear streams of inputs).

For reference, here is syn’s TokenTree type that it uses when parsing Rust syntax.

Examples
type Span = std::ops::Range<usize>;

fn span_at(at: usize) -> Span { at..at + 1 }

#[derive(Clone)]
enum Token {
    Local(String),
    Int(i64),
    Bool(bool),
    Add,
    Sub,
    OpenParen,
    CloseParen,
    OpenBrace,
    CloseBrace,
    // etc.
}

enum Delimiter {
    Paren, // ( ... )
    Brace, // { ... }
}

// The structure of this token tree is very similar to that which Rust uses.
// See: https://docs.rs/syn/0.11.1/syn/enum.TokenTree.html
enum TokenTree {
    Token(Token),
    Tree(Delimiter, Vec<(TokenTree, Span)>),
}

// A function that turns a series of nested token trees into a linear stream that can be used for parsing.
fn flatten_tts(eoi: Span, token_trees: Vec<(TokenTree, Span)>) -> BoxStream<'static, Token, Span> {
    use std::iter::once;
    // Currently, this is quite an explicit process: it will likely become easier in future versions of Chumsky.
    Stream::from_nested(
        eoi,
        token_trees.into_iter(),
        |(tt, span)| match tt {
            // For token trees that contain just a single token, no flattening needs to occur!
            TokenTree::Token(token) => Flat::Single((token, span)),
            // Flatten a parenthesised token tree into an iterator of the inner token trees, surrounded by parenthesis tokens
            TokenTree::Tree(Delimiter::Paren, tree) => Flat::Many(once((TokenTree::Token(Token::OpenParen), span_at(span.start)))
                .chain(tree.into_iter())
                .chain(once((TokenTree::Token(Token::CloseParen), span_at(span.end - 1))))),
            // Flatten a braced token tree into an iterator of the inner token trees, surrounded by brace tokens
            TokenTree::Tree(Delimiter::Brace, tree) => Flat::Many(once((TokenTree::Token(Token::OpenBrace), span_at(span.start)))
                .chain(tree.into_iter())
                .chain(once((TokenTree::Token(Token::CloseBrace), span_at(span.end - 1))))),
        }
    )
}

Trait Implementations§

Converts to this type from the input type.
Converts to this type from the input type.

Please note that Chumsky currently uses character indices and not byte offsets in this impl. This is likely to change in the future. If you wish to use byte offsets, you can do so with Stream::from_iter.

Converts to this type from the input type.

Please note that Chumsky currently uses character indices and not byte offsets in this impl. This is likely to change in the future. If you wish to use byte offsets, you can do so with Stream::from_iter.

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
The number of items that this chain link consists of.
Append the elements in this link to the chain.

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.