I wrote a grammar like this:
grammar StatementFormat {
token TOP { (<plain> | '%' <placeholder>)* }
token plain { <-[%]> }
token placeholder {
| <verb>
| <noun>
| <adverb>
}
token verb {
'v'
{
# some actions
}
}
token noun {
'n'
{
# some actions
}
}
token adverb {
'a'
{
# some actions
}
}
}
So I could use it to parse strings like "someone %v %n %a".
However, I found there were so many usages like "%v %n %a", I'd like to give it an alias, say, "%b" such that parsing "someone %b" is equivalent to parsing "someone %v %n %a".
So is there a way to do that?
Of course, token alias { 'b' { ... } }
can do that. But in that way I need to repeat that action code. I am wondering if there exists a simpler way.
So, there is one obvious way, which is to simply put the code for the actions into subroutines and then in the b
alias, call them:
sub verb-action($/) { }
sub noun-action($/) { }
sub adverb-action($/) { }
grammar StatementFormat {
# rest goes here
token verb {
'v'
{ verb-action($/) }
}
token noun {
'n'
{ noun-action($/) }
}
token adverb {
'a'
{ adverb-action($/) }
}
token alias {
'b'
{
verb-action($/);
noun-action($/);
adverb-action($/);
}
}
}
But where'd be the fun of that?
Instead, I'd recommend using the built-in action object feature of grammars.
It goes like this: you have a separate class with the actions as methods, with the same name as the grammar actions:
class StatementFormatActions {
method verb($/) { ... }
method noun($/) { ... }
method adverb($/) { ... }
}
And when you call parse
, you pass an instance of that action class along:
StatementFormat.parse($string, :actions(StatementFormatActions.new));
Then when you introduce the alias
token, you can also introduce an alias
method:
method alias($/) {
self.verb($/);
self.noun($/);
self.adverb($/);
}
Inside the actions you can also call make
or $/.make(...)
to attach the result of your actions to the match object (then available in$/.made
) to populate an AST from your parse tree.
(You might also like my book on grammars which has several examples and more in-depth explanations. Sorry for the plug, could not resist).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With