Comments (8)
I’ll give it a look today to see what I can do to get it to give you the op spanned. A quick and dirty way to do it would be to use the span’s of the expressions to calculate the span of the operator, as the operator’s span is the space between the two expr’s (though whitespace makes that not 100% true)
from chumsky.
I think there's a certain value in having access to the entire parsed operator. For example, when parsing sufficiently complex mathematical expressions, then there is Knuth's up arrow notation. https://en.m.wikipedia.org/wiki/Knuth%27s_up-arrow_notation Which has an operator with an exponent. That would be most easily parsed by writing a "up arrow followed by exponent" parser for the operator.
Excellent point. I’ll give it a shot tonight and see what I can do!
from chumsky.
I did try map_with_span
, but that gives me a PrattOpOutput
. I'm not sure if I can do anything with it.
On that note, why is type InfixBuilder<E> = fn(lhs: E, rhs: E) -> E;
a fn
? Most other chumsky APIs accept a Fn
, which makes some tasks much easier.
Edit: I see, it's because getting a Fn
to work in that case is tricky #464 (comment)
Would it be possible to extend the InfixBuilder to also have access to the infix token parser result? Same for prefix and postfix parsers. Then it would at least be possible to add some info to the token parser, and pass it into the infix builder.
from chumsky.
This is my attempt.
https://github.com/zesterer/chumsky/compare/main...stefnotch:pratt-with-op?expand=1
I hope it's roughly the right direction, but one thing that's missing is the ability to write build
functions that take an operator that has a different type. For example, here the build function takes a char
as the operator, and two Expr
s as the children. Supporting this probably requires passing another generic type through all the functions.
from chumsky.
I think there's a certain value in having access to the entire parsed operator. For example, when parsing sufficiently complex mathematical expressions, then there is Knuth's up arrow notation.
https://en.m.wikipedia.org/wiki/Knuth%27s_up-arrow_notation
Which has an operator with an exponent. That would be most easily parsed by writing a "up arrow followed by exponent" parser for the operator.
from chumsky.
So, here is some API questions that I have. How does this look?
let parser = atom
.pratt(choice((
left_infix(just('-'), 0, |lhs, op, rhs| Expr::Sub(Box::new(lhs), Box::new(rhs))),
left_infix(just('+'), 0, |lhs, op, rhs| Expr::Add(Box::new(lhs), Box::new(rhs))),
)))
.with_postfix_ops(
// For postfix the `op` is on the right
postfix(just('!'), 0, |lhs, op| Expr::Factorial(Box::new(lhs))),
)
.with_prefix_ops(
// For prefix the `op` is on the left
prefix(just('-'), 0, |op, rhs| Expr::Negate(Box::new(rhs))),
)
.map(|x| x.to_string());
Or do we follow str::split_once
and str::rsplit_once
and keep the op
placement consistent so that both use fn(Op, Expr) -> Expr
from chumsky.
That looks like a good API. I'd keep the |lhs, op|
design, if the infix operator's callback is |lhs, op, rhs|
.
If it's |op, lhs|
, then I'd expect the infix operator's callback to also look roughly like that. That's actually what I did above, mostly because I wanted to have an easy time implementing it. There I have an API that looks like left_infix(just('-'), 0, |op, [lhs, rhs]| Expr::Sub(Box::new(lhs), Box::new(rhs)))
. That made using the current Mode API very easy.
https://github.com/zesterer/chumsky/compare/main...stefnotch:pratt-with-op?expand=1#diff-350f258948b06701ad68bdfb8528d5fdc35c29e5d6a4bdbd0c7673eea00a7e3fR365-R366
from chumsky.
Did you have any luck with a proper implementation so far, or are some parts trickier than expected? Is there anything I could do to help?
In my little experiments with extending the Pratt parsing implementation, I never managed to figure out what exactly Expr
in impl<'a, P, Expr, I, O, E> ParserSealed<'a, I, PrattOpOutput<PrefixBuilder<Expr>>, E>
was used for, which sadly limited my understanding of that bit of code.
from chumsky.
Related Issues (20)
- Pratt parsing with non-associative operators HOT 2
- Update examples HOT 1
- Better Developer Experience HOT 1
- alpha-1.0.0-alpha.6 release broken? HOT 4
- Indentation example: incorrect "end of input" HOT 2
- Idea: conditonal parser, which takes a parser and a condition HOT 4
- or combinator prefers output of second parser, even if first parser succeeds HOT 14
- when use tokio::spawn i meet problem anyone can help HOT 6
- `nested_in()` + `repeated()` produce incorrect error spans. HOT 5
- Failed to compile benches: no method named `slice` found
- `ContainerExactly` impls for `Rc` and `Arc` are unsound HOT 2
- Clone trait bounds not satisfied HOT 2
- Trait bound not satisfied on foldl HOT 2
- Input lifetimes HOT 4
- bug: couldn't build `examples/foo.rs` HOT 1
- Query : Create a parser that parses a vec of patterns HOT 7
- Crashed while parsing markup text HOT 4
- Fix SpannedInput HOT 1
- Trying to run the `nano_rust.rs` example using `chumsky = "1.0.0-alpha.6"` HOT 4
- Question: Using `map_with` to get spans HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from chumsky.