Курс 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

Коментарі

  1. <number>+ % '+' зіставляється з одним або більше числами, розділеними знаками +, — модифікатор % описує розділювач між повтореннями.

  2. Метод дії виконується, коли зіставляється TOP. make прикріплює обчислене значення — суму чисел, — яке .made читає назад після розбору.

  3. 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* ].)

Навігація курсом

Граматика, що додає   |   Збираємо все разом