Basically, the question is more about grammars but I think that it could be more of a interesting exercise on dynamic variables.
I have a grammar role with a prototyped token (the example is simplified to demonstrate the idea):
proto token foo {*}
token foo:sym<a> {
:my $*delimiter = q<">;
\" ~ \" <value>
}
token foo:sym<b> {
:my $*delimiter = q<'>;
\' ~ \' <value>
}
token value {
.+? <?before $($*delimeter) || $($*custom-delimiter)>
}
When the role is consumed by a grammar I want the $*custom-delimiter
to be set by the grammar. Of course, I can declare it everywhere where <foo>
is needed. But sometimes it is ok to have it pre-initialized with a universal default. Something like:
{ $*custom-delimiter //= $default-delimiter }
in the value
token would work. But external pre-declaration would still be needed.
I hoped that:
our $*custom-delimiter is export = $default-delimiter;
in the scope of module where the role is declared would work. But apparently it doesn't. So, the question is: are there any elegant solutions to this?
Actually, I also hope that the solution would allow to move declaration of $*delimiter
in foo
outside of the token definitions too.
As a side note: my first thought was about adding a parameter to the token. But having absolutely identical signatures for each variant is looking terrible too:
token foo:sym<a> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<b> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<c> ( $*custom-delimiter = $default-delimiter ) {
}
Another approach is to have something like:
token pre-foo ( $*custom-delimiter = $default-delimiter ) {
<foo>
}
In this case an additional method would be required in actions class to propagate $/<foo>.ast
one level up.