Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide more advanced examples #293

Open
uzytkownik opened this issue Jul 15, 2020 · 3 comments
Open

Provide more advanced examples #293

uzytkownik opened this issue Jul 15, 2020 · 3 comments

Comments

@uzytkownik
Copy link

I'm trying to implement a generic parser:

    BinExpr<SubExpr, Op> := SubExpr (Op SubExpr)*

However I run into number of issues:

  • I cannot reuse subexpr directly as parsers are effectivly non-clonable (issue Auto-derive of Copy/Clone results in too strict requirements on input #283)
  • There doesn't seems to be a primitive suitable for it (for example sepBy ignores separator)
  • Writing parser by hand is challanging:
    • Many of the helper functions depend on ParseMode
    • Existing implementation of many etc. heavily use internal macros making them non-example
    • There seems to be no documentation on how state in partial parsing behaves and what are the invariants
@Marwes
Copy link
Owner

Marwes commented Jul 15, 2020

I cannot reuse subexpr directly as parsers are effectivly non-clonable (issue #283)
There doesn't seems to be a primitive suitable for it (for example sepBy ignores separator)

let sub_expr = || parser;
(sub_expr(), many((op, sub_expr()))

Should work.

There are also a few chain parsers like https://docs.rs/combine/4.2.1/combine/parser/repeat/fn.chainl1.html or https://github.com/Marwes/combine-language which provides an expression parser that takes precendence into account

Writing parser by hand is challanging:

Yes, writing your own parser is largely internal now. However for a simple, custom parser you can always use https://docs.rs/combine/4.2.1/combine/fn.parser.html which is basically as efficient as you are going to get without needing to understand the whole Parser trait.

@uzytkownik
Copy link
Author

I cannot reuse subexpr directly as parsers are effectivly non-clonable (issue #283)
There doesn't seems to be a primitive suitable for it (for example sepBy ignores separator)

let sub_expr = || parser;
(sub_expr(), many((op, sub_expr()))

Should work.

That was my first attempt. Unfortunately this makes the size of type exponential in layers. With 15 layers it makes the size of type of order of 32768 which effectively hangs even debug build of rust.

(On second though - the clone would not help)

Writing parser by hand is challanging:

Yes, writing your own parser is largely internal now. However for a simple, custom parser you can always use https://docs.rs/combine/4.2.1/combine/fn.parser.html which is basically as efficient as you are going to get without needing to understand the whole Parser trait.

I'll take a look.

@Marwes
Copy link
Owner

Marwes commented Jul 15, 2020

For recursive parsers there is also https://docs.rs/combine/4.2.1/combine/parser/combinator/fn.opaque.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants