-
Notifications
You must be signed in to change notification settings - Fork 790
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
Precedence parsing #1362
base: main
Are you sure you want to change the base?
Precedence parsing #1362
Conversation
This comment has been minimized.
This comment has been minimized.
Remove unused code
The parser really cant work without it and the helpers dont make much sense without the parser.
24ef4a1
to
7f99f1a
Compare
Due to the lack of contrary opinions I have decided to label the current behaviour with ambiguous expressions as intentional. This was done with the following reasons:
|
There are no guidelines on what parser specifically belong in nom or not (or if it exists I havent found it in the contribution guide).
To me this seperate crate still sounds like an open decision. And since I dont know of any such crate existing as of yet I figured I would take my chances and get it into standard nom.
Could you tell me where Im forcing complete input? If one of the operand or operator parser returns |
nevermind I miss understand. |
That's a lot to pass into a single function at once, especially since some of the arguments correspond to aspects of the precedence parser that not everyone will use. Maybe the API should use the builder pattern instead? |
5 parameters in total. 3 of which are always required.
I dont think making a builder pattern for 2 optional parameters would be that great. A builder pattern would also either replicate the current API pretty closely (i.e. a single parser for each category) or I would have to use dynamic dispatch (to maintain a list of parsers for each category). And I would really like to avoid dynamic dispatch if possible. Also there is nothing preventing you from extracting the parsers for the individual operand or operator groups into their own functions and then just passing those to the precedence parser. Same with the fold function. I just put it all in one place to give a comprehensive example of how it works. Edit: Looking over the docs 5 parameters dont seem that out of line. There are plenty of parser that take 3 or 4 parameters, not counting alt and permutation which can (kind of) take up to 21 parameters. There is even an already existing parser with 5 parameters, |
hi! just fyi, I'll review that on saturday or sunday, it looks like a great addition to nom :) |
@Geal Any update on this? |
This looks very useful, it would certainly clean up some of my parsers. @cenodis would you consider releasing this as a separate crate, if it doesn't look like it's making it into nom proper? |
Great, a feature that I need is stuck in a PR that's been sitting around for 6 months. @Geal can you please take a look at this? |
It's been a weird 6 months for my open source work honestly 😅 |
In case anybody else needs it: I turned the contents of this PR into a little crate that works with nom 7: https://github.com/mullr/nom-7-precedence. I'm looking forward to being able to delete it in the future, once nom 8 is a thing! |
This PR introduces a new module with parsers that can handle operator precedence in expressions. It was written with the intent to allow quick and easy translation of a usual operator precedence table into a nom parser. Individual operators and operands are parsed via nom parsers allowing for easy integration with existing parsers.
Example usage (very simple integer calculator):
TODOs
All elements of this module are documented and I cant think of anything more to add.
I have done my best to write good documentation but some feedback would be appreciated. I still feel like some parts could be improved but I have no concrete ideas right now.Tests for parser failures now exist.
Currently the tests for precedence only check for positive results (i.e. successful parses). I would like to get some cases with invalid input as well. I have looked at how the existing tests handle this but the current error handling in nom escapes me. Help with this would be nice.A "fail" parser now exists in nom and can be used to specify "no operators of this kind". I see no other significant problems with the API.
The current API I have come up with feels solid for the most part but I still think theres some room for improvement. Especially when handling languages that may not have certain classes of operators (for example a language with no postfix operators). This necessitates the use of a parser that always fails, but a parser with that functionality does not exist in nom so workarounds likeverify(tag(""), |_: &str| false)
are needed.The tests now have an example containing AST generation, function calls and ternary operators using this parser.
I would like to add more examples into the recipes or example section. Especially for more involved expression containing things like function calls and ternary operators.Open Questions
(see this comment for more details about this)Resolution: The current behaviour is sufficient. See here for reasoning.