Мы уже видели, как сделать грамматику для разбора чисел. Но сами по себе грамматики дают лишь ответ, удовлетворяет ли строка заданным правилам. Обычно еще требуется что-то сделать с имеющимися данными. Для этого к грамматике надо добавить действия (actions).
Рассмотрим простейшее действие на примере грамматики для разбора даты.
grammar DateStr { token TOP { [ | <year> <sep> <month> <sep> <day> | <day> <sep> <month> <sep> <year> ] { printf "--> %4i-%02i-%02i\n", $<year>, $<month>, $<day> } } token year { \d ** 4 } token month { \d ** 1..2 } token day { \d ** 1..2 } token sep { <[-./]> } } my @tests = < 2018-02-26 2018-2-26 26.02.2018 >; for @tests -> $t { print "$t\t"; my $r = DateStr.parse($t); }
Грамматика разрешает один из двух видов формата даты: YYYY-MM-DD или DD-MM-YYYY. Разделителем может быть дефис или точка.
Как только найдено соответствие, Perl 6 выполняет блок кода — в нашем примере он выделен цветом.
Поскольку действие должно выполняться независимо от того, какая ветвь правила TOP совпала, обе альтернативы взяты в группирующие скобки.
Внутри действия совпавшие части доступны как элементы объекта $/, например, $<year>.
Программа успешно разбирает все три примера и печатает даты в едином формате:
2018-02-26 --> 2018-02-26 2018-02-26 --> 2018-02-26 2018-2-26 --> 2018-02-26 26.02.2018 --> 2018-02-26