Giter VIP home page Giter VIP logo

Comments (12)

Marwes avatar Marwes commented on June 1, 2024 29

From reddit https://www.reddit.com/r/rust/comments/6s792a/combine_250_and_300alpha1/dlcgy0l/

Macros vs traits is the most visible difference but that is for the most part just syntax. I think traits still increase compile times to some extent but I would argue it is fairly negligible at this point (barring a regression in rustc which happened ~1 week ago in rustc rust-lang/rust#43613).

That combine uses traits used to be awkward when writing small reusable parsers, but with addition of the parser! macro I would argue that has been more or less completely solved (and with impl Trait it will be completely solved)

For more qualitative differences. combine back in 1.0.0 used to be noticeably slower than nom since I aimed for it to produce good errors. That slowness was fixed almost entirely in 2.0.0 (without sacrificing any error information, modulo the bug which was fixed in 3.0.0) however with combine only being a few percent slower on the benchmarks I ran. From what I can gather, these few percents come down to combine generating more or just more complex drop glue compared to nom. With 3.0.0 combine will be able break even or overtake nom by a few percent (as long as nothing else changes) if one opts for cheaper/more specialized errors.

Due to combine not focusing on fast byte level parsers immediately it used to lack conveniences for that but I think it should be pretty close now that integer parsers are added. I believe nom also has bit-level parsers which is something that combine do not have.

nom has some facilities for writing state machines to feed input into the parser which combine do not have. I have never had a need for this so I didn't want to commit to a flawed and unused design. If someone needs something like that I would be interested in some discussion though!

combine has a lot better input reading facilities since it can handle everything between Iterator and std::io::Read to already in memory inputs such as&[T] or &str. nom on the other hand only supports &[T] (&[u8]?) and &str.

Just because I think it is worth mentioning again, combines error reporting is a lot better for the effort put in when writing parsers.

In combine

char('!').or(digit()).or(letter())
    .parse("?")// Unexpected '?' expected '!', 'digit' or 'letter'.
char('!').or(digit()).or(letter())
    .expected("something")
    .parse("?")// Unexpected '?' expected 'something'

In nom you get one or several error codes which need to be returned manually and handled separately. Though you can probably get nice errors, it is not without a lot of work. (Please correct me if I have misunderstood anything about this)

https://github.com/Geal/nom/blob/master/doc/error_management.md#error-management

combine is a lot smaller than nom but its tutorial(s) could be expanded (Markdown).

$ tokei nom                                                                       
-------------------------------------------------------------------------------   
 Language            Files        Lines         Code     Comments       Blanks    
--------------------------------51         2451            0            0    
 Rust                   40        17646        13015         2934         1697    
 Plain Text              2           32           32            0            0    
 TOML                    1           54           42            3            9    
-------------------------------------------------------------------------------   
 Total                  53        20183        15540         2937         1706    
-------------------------------------------------------------------------------   

$ tokei combine                                                                   
-------------------------------------------------------------------------------   
 Language            Files        Lines         Code     Comments       Blanks    
-------------------------------------------------------------------------------   
 JSON                    1          317          317            0            0    
 Markdown                2          271          271            0            0    
 Rust                   16         8943         6053         2200          690    
 sh                      1            8            6            1            1    
 Plain Text              1          494          494            0            0    
 TOML                    2           53           37            1           15    
-------------------------------------------------------------------------------   
 Total                  23        10086         7178         2202          706    
-------------------------------------------------------------------------------

nom has a lot of parsers already written in it which is something that should not be underestimated when deciding on a library https://github.com/Geal/nom#parsers-written-with-nom.

from combine.

shaitao avatar shaitao commented on June 1, 2024 4

I don't like macros, it's hard to read and understand, especially macros in macros.
I tried combine; but there is a lot of things that I don't know which situation should to use them.

from combine.

Marwes avatar Marwes commented on June 1, 2024

Its a bit short but I made this comment on reddit a while back https://www.reddit.com/r/rust/comments/58nmzg/combine200_now_a_fast_parser_combinator_library/d9343n3/. Might be worthwhile to make a more through comparison but I dunno.

from combine.

GunpowderGuy avatar GunpowderGuy commented on June 1, 2024

how does nom stack against parsers combinators based on structs ? , the author of pom claims they are inherently better .

from combine.

GunpowderGuy avatar GunpowderGuy commented on June 1, 2024

will combine continue to be dependant on the parser macro to do away with bloat ?
i am interested in parser combinators as a metaprogramming alternative to macros ( building a modular compiler based upon them ? )

from combine.

GunpowderGuy avatar GunpowderGuy commented on June 1, 2024

Both result in slower compilation that macro based ones ( due to reliance on zero abstractions to compile away intermediate data structures and traits , respectively ) , but which one will be benefited the most from rustc advancements ( caching compiler , more rust specific abstractions , other ones which have only been planed )

from combine.

Marwes avatar Marwes commented on June 1, 2024

how does nom stack against parsers combinators based on structs ? , the author of pom claims they are inherently better .

It is about the same, a few percent in either direction on equivalent parsers. Debugging should be better with structs though as it says in the POM readme.

will combine continue to be dependant on the parser macro to do away with bloat ?

Once impl Trait gets to stable the macro will no longer be necessary. If you are fine with using nightly then you can just use impl Trait today and ignore it.

i am interested in parser combinators as a metaprogramming alternative to macros ( building a modular compiler based upon them ? )

Since combines parsers need to be statically defined there are limits to its flexibilty in metaprogramming since you will need to define all parsers you may need at compile time.

Both result in slower compilation that macro based ones ( due to reliance on zero abstractions to compile away intermediate data structures and traits , respectively ) , but which one will be benefited the most from rustc advancements ( caching compiler , more rust specific abstractions , other ones which have only been planed )

They should get the same sort of speedups percentagewise of their current compile times (though since combine is slower to compile now, it will benefit more in absolute terms).

from combine.

GunpowderGuy avatar GunpowderGuy commented on June 1, 2024

Thanks for your quick response

from combine.

GunpowderGuy avatar GunpowderGuy commented on June 1, 2024

So combine will achieve the same with less code , and continue to improve its compilation time but end up slower ?

from combine.

Marwes avatar Marwes commented on June 1, 2024

I think combine and nom are fairly similar in how much code users need to write. What i meant above is that combine has a much smaller and approachable code base.

With equivalently constructed parser then combine will likely always be somewhat slower to compile due to typechecking. Only way it can be faster is that combine might let you construct a smaller parser (and thus less code to compile) than nom is able to.

Do consider that part of the reason that combine is slower to compile is that it has a lot more flexibility to how and what it parsers.

from combine.

GunpowderGuy avatar GunpowderGuy commented on June 1, 2024

" it has a lot more flexibility "

You mean compared to both nom and pom ? isn't the latter built with a different approach ( or am i miss understanding the implications of peg ? )

from combine.

Marwes avatar Marwes commented on June 1, 2024

You mean compared to both nom and pom ?

Yeah, nom and pom only handles &str and &[T] while gluon can handle anything implementing StreamOnce (and a few other Stream* traits). This extra flexibility makes the instantiated types larger and thus it takes longer to compile.

from combine.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.