ptal / oak

A typed parser generator embedded in Rust code for Parsing Expression Grammars
Apache License 2.0
142 stars 14 forks source link

Stream as ground type #87

Closed ptal closed 7 years ago

ptal commented 8 years ago

A generated function currently have this header:

pub fn parse_non_terminal_bis<S>(mut state: ParseState<S, ()>)
     -> ParseState<S, (char, Vec<char>)> where
     S: CharStream;

Parsing functions are parametric in the type of the stream. This is not necessary. Indeed we design a grammar for a specific type of stream, either a stream of char, a stream of token, a stream of bytes for binary protocol, ... Being generic at this level is thus useless. It is also problematic for external parser and semantic action, they see a stream similarly to the parsing function, here a stream that implements CharStream. They cannot expect a stream that provides additional information and it makes generic code useless.

A way out would be to gather the type bounds generated by external function and add these in the parsing functions. It couples our implementation more to the Rust internals, is complicated and even impossible for functions declared outside the procedural macro.

Therefore we choose to simply ask the user to add a type declaration of the expected underlying stream:

type Stream<'a> = StrStream<'a>;

pub fn parse_non_terminal_bis<'a>(mut state: ParseState<Stream<'a>, ()>)
     -> ParseState<Stream<'a>, (char, Vec<char>)>

However, if a user want to be generic over the stream, he still can provide a type such as Box<SomeStreamTrait>.

Design