Course of Raku / Regexes and grammars / Grammars / Action classes

Inline actions vs action classes

You now have two ways to attach meaning to a parse. Which should you use?

Inline actions put a { make … } block right inside the token:

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

They are quick to write and fine for a tiny grammar or a one-off script. The cost is that the pattern and the logic are tangled together.

An action class keeps the two apart — the grammar describes the shape, the action class describes the meaning:

grammar Sum {
    token TOP { <a> '+' <b> }
    token a   { \d+ }
    token b   { \d+ }
}

class SumActions {
    method TOP($/) { make $<a>.made + $<b>.made }
    method a($/)   { make $/.Int }
    method b($/)   { make $/.Int }
}

This separation has real advantages as a grammar grows: the pattern stays readable, and you can pair one grammar with several action classes — one that evaluates, one that pretty-prints, one that builds a data structure — without touching the grammar at all.

The rule of thumb: inline actions for something small and throwaway, an action class for anything you will maintain or reuse.

Practice

Complete the 1 quiz that covers the contents of this topic.

Course navigation

Quiz — make   |   Quiz — Action classes


💪 Or jump directly to the exercises in this section.