Курс языка программирования Raku / Приложение 🆕 / Типы и текстовые машины / Регулярные выражения и грамматики / Exercises / Грамматика, которая складывает
Решение: Грамматика, которая складывает
Вот один из возможных вариантов решения задачи.
Код
grammar Sum {
token TOP { <number>+ % '+' }
token number { \d+ }
}
class SumActions {
method TOP($/) { make [+] $<number>.map(*.Int) }
}
say Sum.parse('3+4+5', actions => SumActions).made;🦋 Исходный код можно найти в файле grammar-sum.raku.
Вывод
12Комментарии
<number>+ % '+'сопоставляется с одним или несколькими числами, разделёнными знаками+: модификатор%описывает разделитель между повторениями.Метод действия выполняется, когда сработал
TOP.makeприкрепляет вычисленное значение — сумму чисел, — которое.madeсчитывает после разбора.Tokenникогда не пропускает пробелы, поэтому эта грамматика строга к своему входу:'3+4+5'разбирается, а'3 + 4 + 5'— нет (.parseвозвращаетNil). Чтобы принимать пробелы вокруг плюсов, сделайтеTOPправиломrule— и отделите квантификатор от его атома:grammar Sum { rule TOP { <number> + % '+' } token number { \d+ } }
В
ruleпробел в шаблоне означает неявный вызов<.ws>. Записанное как<number> + % '+', с пробелом перед квантификатором+, это неявное пробельное правило покрывает всё повторение, включая разделители, — поэтому разбираются и'3+4+5', и'3 + 4 + 5', а сумма в обоих случаях равна12. (Если вы предпочитаете остаться сtoken, выпишите пробелы прямо в разделителе:<number>+ % [ \s* '+' \s* ].)