Курс языка программирования 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; # 5make и made — это мост от «совпало» к «вот
его смысл». Встроенные блоки работают, но смешивают шаблон с логикой;
следующий раздел переносит эту логику в отдельный класс действий.
Практика
Пройдите 1 тест по содержанию этой темы.
Навигация по курсу
← Тест — Дерево совпадения | Тест — make и made →
💪 Или перейдите сразу к упражнениям этого
раздела.