Курс Raku / Додаток 🆕 / Типи та текстові машини / Регулярні вирази та граматики / Вправи / Граматика, що додає
Розв’язання: Граматика, що додає
Ось одне з можливих розв’язань задачі.
Код
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* ].)