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

Коментари

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

Навигация в курса

Граматика, която събира   |   Всичко наедно