-
Notifications
You must be signed in to change notification settings - Fork 82
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
Additional features for choosing how to parse input #53
Additional features for choosing how to parse input #53
Conversation
Add support for custom selector
Fix doc links
Fixed godev links uses only one hyphen
Hi Noah, thank you for contributing such a great feature. I saw just a few small issues. I will mark them directly in the code. |
And thanks for fixing some additional bugs. |
language.go
Outdated
// Late allows late-binding of a language so that languages can be | ||
// self-referencing. The return value of the passed function will be bound to | ||
// the language. | ||
func Late(fn func(late Language) Language) (binding Language) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure you don't need this and could use somethig like
var a = PrefixExtension('x', parseX)
var b = PrefixExtension('y', parseY)
func parseX func(context.Context, *Parser) (Evaluable, error){
p.ParseSublanguage(b)
}
func parseY func(context.Context, *Parser) (Evaluable, error){
p.ParseSublanguage(a)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, indeed, both this function and PrefixLanguage
are trivially built using the other additions, and with entirely public interfaces.
Removing PrefixLanguage
seems harmless, but my only concern about removing Late
is that users may not discover such a mechanism for implementing recursive invocation by themselves. In many parser combinator libraries, in addition to the base set of parser constructs, they also expose some "patterns" that are built on top of the primitives, like Sequence
, Many
, Optional
, etc. Do you think it would it make sense to have a patterns.go
that has these type of utility language constructors in it?
For now, I've removed it altogether, but let me know if you'd like me to add it back in a different spot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that could be a problem. I think example tests may help.
…Extension, and place ParseSublanguage under the parser
Hi!
We implemented a
kubectl
-like JSONPath template language on top of Gval, which we have been using in our production environment for about a year now with great success. To implement it we needed to add additional features to the base library.For the languages:
Language.ChainEvaluable(ctx, parser)
: Immediately run this language when the next token is consumed by the given parser.PrefixLanguage(prefix, lang, next)
: When the parser encounters the given prefix, it switches to another language. When that language cannot consume any more tokens, control is returned to the calling language and thenext
callback is invoked. Higher level interface forLanguage.ChainEvaluable(...)
.Init(next)
: Rather than immediately callingparser.ParseExpression()
, you can perform some setup work (like configuring the parser to handle whitespace or tokens a specific way).Alternate(next)
: Called if no other parsing construct matches the given input.Late(func(outer Language)) Language
: Allow late-binding of languages. This way you can embed a language in itself recursively. This is useful for some template languages, or, say, Bash string/command interpolation.For the token parser:
SetMode
,SetWhitespace
,SetIsIdentRuneFunc
: Modify the underlying Go text scanner with the corresponding configuration.I also fixed a small bug in the infix operator merging strategy.
You can see our complete implementation of the JSONPath template language I mentioned here as an example:
Let me know if you have any questions or suggestions for improvements. I hope you find these additions as useful as we have!