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


💪 Или преминете направо към упражненията в този раздел.