Course of Raku / Regexes and grammars / Grammars / The parse tree, make and made
make and made
Instead of digging values out of the tree afterwards, you can attach
a value to a match while parsing. Within a token’s body
you can embed a code block — an inner { … }
written among the pattern — which runs as soon as matching reaches it.
Inside that block, the function make stores a value on the
current match:
grammar OneNum {
token TOP { <number> { make $<number>.Int } }
token number { \d+ }
}When TOP matches, the inner
{ make $<number>.Int } block runs — the outer braces
are just the token’s body — and stores the integer on the match. You
read it back afterwards with made (or its alias
.ast):
say OneNum.parse('42').made; # 42Because we stored $<number>.Int, the value handed
back by made is a real Int — the number
itself, not the match object:
say OneNum.parse('42').made + 1; # 43Note that this particular + 1 would give 43
even without the .Int, since a match numifies to its digits
in arithmetic. The point of calling .Int is that the
stored value genuinely is a number — which is
what you want once it is kept in a data structure or passed on, rather
than the raw match.
The stored value can be anything — a number, a string, an array, an object. A token can also combine the values its sub-tokens made. For example, summing two captured numbers:
grammar Sum {
token TOP { <a> '+' <b> { make $<a>.Int + $<b>.Int } }
token a { \d+ }
token b { \d+ }
}
say Sum.parse('2+3').made; # 5make and made are the bridge from “it
matched” to “here is the meaning”. Putting the blocks inline works, but
it mixes the pattern with the logic; the next section moves that logic
into a separate action
class.
Practice
Complete the quiz that covers the contents of this topic.
Course navigation
← Quiz — The match tree | Quiz — make and made →
💪 Or jump directly to the exercises in this
section.