m4rw3r / chomp

A fast monadic-style parser combinator designed to work on stable Rust.
Apache License 2.0
243 stars 19 forks source link

`impl Trait` for Version 2.0.0 of Chomp #53

Open m4rw3r opened 8 years ago

m4rw3r commented 8 years ago

This is the impl Trait based monad implementation of Chomp for Rust Nightly. It is not intended to become the 1.0.0 of Chomp, current master is using the monad-like syntax where an input is manually threaded. Instead version 2.0.0 will be the full-monad. See #50 for the reasoning why.

Still heavily work in progress. An alpha is intended for release once the documentation-issue is solved.

m4rw3r commented 8 years ago

I should probably rename this branch, it is no longer an experiment :)

m4rw3r commented 7 years ago

How to properly handle the case of peek_next + switch? All the branches of the switch return parsers of different types (and many times different sizes too). Forcing the use of boxed() on each of the returned parsers would be far from ideal.

Example:

macro_rules! ret { ( $e:expr ) => { any().then(ret($e)) } }

peek_next().bind(|c| match c {
    b'{' => ret!(Token::StartObject),
    b'}' => ret!(Token::EndObject),
    b'(' => ret!(Token::StartArray),
    b')' => // ...
    b'"' => quoted_string(),
    _    => tagged!(b"true",  Token::True).or(
            tagged!(b"false", Token::False).or(
            tagged!(b"null",  Token::Null).or(
            number.or(whitespace))))
})
m4rw3r commented 7 years ago

Seems like https://docs.rs solves the documentation issue, except for providing documentation for master of each of the two versions.

aldanor commented 7 years ago

Great stuff! It looks though as this implementation would currently suffer from the lack the "anonymized enums" capability of impl Trait for merging results of potentially different anynomized types (for object-safe traits), this is something that's been discussed in the tracking issue recently. Otherwise you're basically back to boxing once you have several anonymised results to deal with, as shown in your example above :)

m4rw3r commented 7 years ago

I hope I can find the time soon to continue working on Chomp.

@aldanor I have encountered that issue, or something close to it, with the sep_by parser where the separating parser is not present for the first time it iterates. The solution was to create a small enum-wrapper which matches on a contained Option<P: Parser> and calls the nested parser if present. This did not seem to cause any performance-degradation.

But the more general case will require boxing, if no object-safe enum can be used. Maybe a macro can be used to build an enum for the static case to avoid boxing.

m4rw3r commented 7 years ago

combinators::bounded::ParserConstructor<I> is now implemented by FnMut and the special parser for sep_by