You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'd like a built-in expression to capture both the result of a parsing expression and the input slice that spans it, like $(e) but produces a tuple of (slice spanning e, return value of e). (This is basically the consumed combinator in nom; $$(e) might be a good syntax.)
My motivation is that I'm working on a programming-language parser where each AST node has a location field that's basically a three-tuple: (start index, length, identifier for source file). I can't get the file identifier from the position!() expression, but I've set up the ParseSlice implementation for my file type to insert it. However, since there's no direct access to the input object within the available expressions in peg, the slice operator seems to be the only way to get this value, and if I use slice I don't get the return value of the expression. I think I can work around it for the use-cases I have by pulling the location fields from some of the subexpressions, but the only fully-general solution I can think of would be something like this which parses the expression twice (I haven't tried it, I'm not sure about the return value of &e):
This would be pretty easy to add and would be generally useful. I'm trying to avoid adding more symbols to make grammars easier to read for new users, but $$ is close enough to $ that the difference could be easily documented.
For your use case though, there's an existing feature might be better than repurposing ParseSlice: the undocumented ##method() expression calls input.method(pos). Here's an example of it defined and used in rust-peg's own meta-grammar. This is undocumented because I plan to replace it with a more flexible expression accepting a block of Rust code in the grammar with access to input and position (#284) once I can come up with a good syntax for it.
You could use this to make a customized replacement for position!() that returns the additional info you need. Then wrap it in a generic rule:
For the case where someone needs a value T plus the input slice, I tried doing this, as @bruceiv suggested:
/// Return both the value and slice matched by the rule.
rule with_slice<T>(r: rule<T>) -> (T, &'input str)
= value:&r() input:$(r()) { (value, input) }
This passed all my tests in a moderately complex grammar.
I'd like a built-in expression to capture both the result of a parsing expression and the input slice that spans it, like
$(e)
but produces a tuple of(slice spanning e, return value of e)
. (This is basically theconsumed
combinator in nom;$$(e)
might be a good syntax.)My motivation is that I'm working on a programming-language parser where each AST node has a
location
field that's basically a three-tuple: (start index, length, identifier for source file). I can't get the file identifier from theposition!()
expression, but I've set up theParseSlice
implementation for my file type to insert it. However, since there's no direct access to the input object within the available expressions inpeg
, the slice operator seems to be the only way to get this value, and if I use slice I don't get the return value of the expression. I think I can work around it for the use-cases I have by pulling the location fields from some of the subexpressions, but the only fully-general solution I can think of would be something like this which parses the expression twice (I haven't tried it, I'm not sure about the return value of&e
):The text was updated successfully, but these errors were encountered: