Currently in the process of rewriting my #transpiler from #nom v4.2 to #chumsky v1.0.0-alpha.6 馃

It is a lot of fun so far, but I have to say these type signatures are _wild_!馃槃

I'm still struggling with it far more than I'd like, but I guess it is just a matter of time until intuition kicks in and it will become more and more natural.

Exciting project ahead!馃檪

I'm even able to parse string literals _with escape sequences_ - something I haven't even achieved with nom!

#Rust #RustLang

Sometimes, in order to stay flexible and fit, you need to do some (type) gymnastics 馃じ

Slowly getting the hang of #chumsky #parser combinator #crate 馃

One concept (among others!) I haven't learned yet, but _will_ run into, is #recursion in chumsky. I know, there are good docs on it - it's just something I haven't gotten to yet.

All in all, I'm very happy with chumsky so far. Kudos to its maintainers! 馃檪 馃帺

#Rust #RustLang

@janriemer Recursion couldn't be easier!

let a = recursive(|a| /* definition of a */);

Make sure you don't end up with accidental left recursion though. Check out the docs for the new pratt parser combinator if you want a really neat way to do complex expression parsing.

@jsbarretto This looks very easy indeed - thank you!  

Yes, thank you for the hint regarding left recursion (see little anecdote in second toot). 馃憤

If I understand correctly, `memoized` should be used for left recursive grammars in general, no!?

I always thought pratt parsing was only for parsing expressions (like 1+2*5 etc.), but not general left recursive parsing, but this is more an intuition, so I might be wrong.馃槆

https://docs.rs/chumsky/1.0.0-alpha.6/chumsky/trait.Parser.html#method.memoized

1/2

Parser in chumsky - Rust

A trait implemented by parsers.

@jsbarretto here comes the anecdote (if you are interested):

The grammar I have to parse is left-recursive. When I started the project I painfully run into it by experiencing exponential parsing time (took me quite a while to figure out what was going on).

So I decided to transform the grammar into a right-recursive one. However, this can result into some "ugly" AST structure, so after parsing I transform the AST back into something that resembles the "left-recursive" structure.

2/3

@jsbarretto Now, using chumsky, I'll probably don't need that extra transformation step, but can parse the left recursive grammar directly, which is really nice!

(first, I'll leave the transformation step and right-recursive parsing as is to not have too much refactoring going on at the same time馃槵)

3/3

@janriemer So... Yes, `memoized` does exist, and does allow the parsing of left-recursive grammars. However, it does come with some overhead: if you can rewrite your grammar to be right-recursive, you'll almost certainly be happier in the long run (this goes for pretty much any top-down approach to parsing out there FWIW).

I'd be interested to know what the right-recursive section of your grammar looks like: the pratt parser can almost certainly handle it, whatever it is.

@jsbarretto Thank you for all the tips, Joshua! 馃

So two places in the grammar might be interesting:

1. Conditional Expressions:
Think of something like this:
foo && (bar || baz)

So this might not be very different from math expressions and so pratt parsing should be possible, right!?馃

Here is a direct link to the parsing code and line (鈿狅笍 nom macros ahead!)
https://gitlab.com/seloxidate/selector/-/blob/e6a7aa290c6027c9fd595ed89bebc4d3c1de4773/src/parsers/conditional_expression.rs#L43

1/2

src/parsers/conditional_expression.rs 路 e6a7aa290c6027c9fd595ed89bebc4d3c1de4773 路 seloxidate / selector 路 GitLab

A parser for inline select statements in X++. Written in Rust. 馃

GitLab

@jsbarretto

2. Eval Name:
Basically method calls - think of something like this to parse:
myClass.myMethod(foo.bar())

I can imagine that this might not be suitable for pratt parsing (it's not a classical math expression), but I haven't really put much thought into it yet, so maybe it's perfecty fine to apply pratt parsing!?

Here is a direct link to the parsing code and line (鈿狅笍 nom macros ahead!)
https://gitlab.com/seloxidate/selector/-/blob/e6a7aa290c6027c9fd595ed89bebc4d3c1de4773/src/parsers/eval_name.rs#L16

2/2

src/parsers/eval_name.rs 路 e6a7aa290c6027c9fd595ed89bebc4d3c1de4773 路 seloxidate / selector 路 GitLab

A parser for inline select statements in X++. Written in Rust. 馃

GitLab
Simple but Powerful Pratt Parsing

Welcome to my article about Pratt parsing --- the monad tutorial of syntactic analysis. The number of Pratt parsing articles is so large that there exists a survey post :)

@janriemer Both of these cases can definitely be handled by a pratt parser! The first cases (&& and ||) are just regular binary expressions. The second case (method calls) is just a postfix unary expression, but where the 'operator' is `.method(<expr>)`. Remember that 'operator' doesn't need to be just a single token, it just needs to be 'self-delimiting' (i.e: outside the precedence hierarchy)!

@jsbarretto Nice! Thank you for all the info and explanation!鉂わ笍

After I'll have rewritten my parser with chumsky, I'll try to refactor it back to left recursion again and try to use pratt parsing. I'll definitely let you know then. 馃槈