По сути, вопрос больше в грамматике, но я думаю, что это может быть более интересным упражнением по динамическим переменным.
У меня есть роль грамматики с прототипом токена (пример упрощен, чтобы продемонстрировать идею):
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)>
}
Когда роль используется грамматикой, я хочу, чтобы $*custom-delimiter
быть установлен грамматикой.Конечно, я могу объявить это везде, где требуется <foo>
.Но иногда можно предварительно инициализировать его универсальным значением по умолчанию.Что-то вроде:
{ $*custom-delimiter //= $default-delimiter }
в токене value
будет работать.Но внешнее предварительное объявление все еще будет необходимо.
Я надеялся, что:
our $*custom-delimiter is export = $default-delimiter;
в области действия модуля, в котором объявлена роль, будет работать.Но, видимо, это не так.Итак, вопрос в том, есть ли какие-нибудь изящные решения для этого?
На самом деле, я также надеюсь, что решение позволит переместить объявление $*delimiter
в foo
также за пределы определений токенов.
В качестве примечания: моя первая мысль была о добавлении параметра в токен.Но иметь абсолютно одинаковые подписи для каждого варианта тоже выглядит ужасно:
token foo:sym<a> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<b> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<c> ( $*custom-delimiter = $default-delimiter ) {
}
Другой подход - иметь что-то вроде:
token pre-foo ( $*custom-delimiter = $default-delimiter ) {
<foo>
}
В этом случае в действиях потребуется дополнительный методкласс для распространения $/<foo>.ast
на один уровень выше.