Custom Grammars
our $SYMBOLS = [ # variable sigils and other high precedence operators [ '$' => sig_item => 0, 350 ], # $foo [ '@' => sig_list => 0, 350 ], # @foo [ '%' => sig_hash => 0, 350 ], # %foo [ '.' => op_dot => 340, 0 ], # foo.bar # ++/-- unary prefix/postfix self-modification operators [ '++' => num_inc => 295, 295 ], # foo++, ++foo [ '--' => num_dec => 295, 295 ], # foo--, --foo . . . [ for => cmd_for => 100, 100 ], [ if => cmd_if => 100, 100 ], ];
Thus Spake Andy:
A grammar is, at the simplest level, a collection of operators. The code
above is an extract from the default TT3 grammar. Each entry defines the
operator token, an identifier mapping it to an element module (e.g.
sig_item
is mapped to Template::TT3::Element::Sigil::Item
) and
leftward/rightward precedence levels (leftward for postfix/infix operators binding
to items on their left, rightward for prefix operators bind to items on their
right - some operators are both). Note also that for
, if
and other
command keywords are also operators. Everything is an operator. Everything
is driven by operator precedence.
Creating your own language/dialect with a different set of operators is (almost) as simple as defining a symbol table using a package variable. It's essentially the same thing that we did when we wanted to define a new tagset. Just define some package variables and let the base class make sense of your declaration.
So to cut a long story short, if you don't think a template language should have an assignment operator then you can easily implement your own dialect that does away with it (along with any other that can cause side-effects). How useful that would be in practice remains to be seen... but it's now possible.