Курс по 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* ].)