Курс Raku / Регулярні вирази та граматики / Граматики / Дерево розбору, make і made

make і made

Замість того щоб вигрібати значення з дерева опісля, ви можете прикріпити значення до збігу під час розбору. У тілі токена можна вбудувати блок коду — внутрішні { … }, записані серед шаблону, — який виконується щойно зіставлення до нього дійде. Усередині цього блоку функція make зберігає значення на поточному збігу:

grammar OneNum {
    token TOP    { <number> { make $<number>.Int } }
    token number { \d+ }
}

Коли TOP зіставляється, виконується внутрішній блок { make $<number>.Int } — зовнішні фігурні дужки є просто тілом токена — і зберігає ціле число на збігу. Прочитати його назад можна потім за допомогою made (або його синоніма .ast):

say OneNum.parse('42').made; # 42

Оскільки ми зберегли $<number>.Int, значення, яке повертає made, є справжнім Int — самим числом, а не об’єктом збігу:

say OneNum.parse('42').made + 1; # 43

Зауважте, що саме це + 1 дало б 43 і без .Int, бо в арифметиці збіг перетворюється на число за своїми цифрами. Сенс виклику .Int у тому, що збережене значення справді є числом, — а це саме те, що потрібно, коли воно потрапляє в структуру даних або передається далі, а не залишається сирим збігом.

Збережене значення може бути чим завгодно — числом, рядком, масивом, об’єктом. Токен також може поєднувати значення, які створили його підтокени. Наприклад, сума двох захоплених чисел:

grammar Sum {
    token TOP { <a> '+' <b> { make $<a>.Int + $<b>.Int } }
    token a   { \d+ }
    token b   { \d+ }
}

say Sum.parse('2+3').made; # 5

make та made — це місток від «воно зіставилося» до «ось що воно означає». Розміщення блоків усередині шаблону працює, але змішує шаблон із логікою; наступний розділ переносить цю логіку в окремий клас дій.

Практика

Виконайте 1 тест за змістом цієї теми.

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

Тест — Дерево збігу   |   Тест — make і made


💪 Або перейдіть одразу до вправ цього розділу.