-
Notifications
You must be signed in to change notification settings - Fork 68
Description
First things first
First let me say thanks to all contributors for your great work.
Pigeon has been a great tool and many times have I found myself appreciating the crystal clear documentation!
However, I might have a request.
Request
I'm working on a project where I'm trying to use go constants for input matching in pigeon.
For example:
// definitions.go
package definitions
const (
plus = "+"
percent = "%"
)
func Operators() []string { return []string{plus, percent} }// grammar.pigeon
...
op <- [^ \n\t\ra-zA-Z0-9]+
&{ return helpers.Contains(definitions.Operators(), string(c.text)), nil }
{ return string(c.text), nil }
...
I'm trying to avoid having to repeat all the go definitions in pigeon, so I match liberally on the regex and then narrow it down within the predicate code block.
This works like a charm for parsing valid inputs and correctly returns errors on invalid inputs.
However, the suggestions made in the expected field of the parserError are purely based on the regex and I cannot modify these suggestions through the predicate code block. Since the predicate block is more restrictive than the regex, I'd like to be able to return custom suggestions.
What I tried
I have tried to return errors from the predicate code block, but this does not have the same effect (when returning false, err, the resulting errors of Parse(...) still contains the regex suggestion in the expected block and the predicate block must return false to allow potential subsequent rules to try and match the input).
I have also tried using the labeled failures, but find them hard to work with in more complicated grammar scenarios with many rules.
Conclusion
Since the predicate and regex both affect the outcome of an attempted match, I thought it might be sensible to provide more control in the predicate code block such that it can return its own suggestions in the expected field of a parserError.
For example:
// grammar.pigeon
...
op <- [^ \n\t\ra-zA-Z0-9]+
&{ return helpers.Contains(definitions.Operators(), string(c.text)), definitions.Operators(), nil } // returning match-result (bool), expected ([]string), err (error)
{ return string(c.text), nil }