Raku Books / Perl 6 at a Glance / Regexes and Grammars

Actions

The grammars in Perl 6 allow actions in response to the rule or token matching. Actions are code blocks that are executed when the corresponding rule or token is found in the parsed text. Actions receive an object $/, where you can see the details of the match. For example, the value of $<identifier> will contain an object of the Match type with the information about the substring that actually was consumed by the grammar.

rule assignment {
    | <identifier> '=' <value>
          {say "$<identifier>=$<value>"}
    | <identifier> '=' <identifier>
}

CodeBlockPlaceholder2raku-static rule assignment { | ‘=’ {%var{~$} = +$} | ‘=’ } CodeBlockPlaceholder3

So far, we’ve got an action for assigning a value to a variable and can process the first line of the file. The variable storage will contain the pair {x => 42}.

In the second alternative of the assignment rule, the <identifier> name is mentioned twice; that is why you can reference it as to an array element of $<identifier>.

rule assignment {
    | <identifier> '=' <value>
      {
          %var{~$<identifier>} = +$<value>
      }
    | <identifier> '=' <identifier>
      {
          %var{~$<identifier>[0]} =
          %var{~$<identifier>[1]}
      }
}

CodeBlockPlaceholder5raku-static rule assignment { | () ‘=’ () { %var{$0} = +$1 } | () ‘=’ () { %var{$0} = %var{$1} } } CodeBlockPlaceholder6

Here, the unary ~ is no longer required when the variable is used as a hash key, but the unary + before $1 is still needed to convert the Match object to a number.

Similarly, create the actions for printing.

rule printout {
    | 'print' <value>
      {
          say +$<value>
      }
    | 'print' <identifier>
      {
          say %var{$<identifier>}
      }
}

CodeBlockPlaceholder8 42 42 7 CodeBlockPlaceholder9

As soon as we used capturing parentheses in the rules, the parse tree will contain entries named as 0 and 1, together with the named strings, such as identifier. You can clearly see it when parsing the y = x string:

statement => 「y = x」
 assignment => 「y = x」
  0 => 「y」
   identifier => 「y」
  1 => 「x」
   identifier => 「x」

CodeBlockPlaceholder11raku-static my %var;

grammar Lang { rule TOP { ^ $ } rule statements { + %% ‘;’ } rule statement { | | } rule assignment { | () ‘=’ () { %var{$0} = +$1 } | () ‘=’ () { %var{$0} = %var{$1} } } rule printout { | ‘print’ { say +$ } | ‘print’ { say %var{$} } } CodeBlockPlaceholder12

CodeBlockPlaceholder13raku grammar G { rule TOP {^ $} }

class A { method TOP($/) {say ~$/} }

G.parse(“42”, :actions(A)); ```

Both the grammar G and the action class A have a method called TOP. The common name connects the action with the corresponding rule. When the grammar parses the provided test string and consumes the value of 42 by the ^ \d $ rule, the A::TOP action is triggered, and the $/ argument is passed to it, which is immediately printed.

Course navigation

An interpreter   |   AST and attributes