Aside from the usual plain pattern matching constructs, a few variants of the
match
construct are offered. We'll briefly enumerate a few of these:
matchall
construct is a variant of match
that
executes all matching rules(instead of just the first one) in sequence.
match
statement can have associated cost
expressions. Instead of selecting the first matching rule to
execute as in the default, all matching rules are considered
and the rule with the least cost is executed. Ties are broken by
choosing the rule that comes first lexically. For example:
match (ir) { ADD(LOAD(?r0),?r1) \ e1: { ... } | ADD(?r0,LOAD(?r0)) \ e2: { ... } | ADD(?r0, ?r1) \ e3: { ... } | ... }
match
construct can be modified with the while
modifier, as in the following example. A match modified thus is
repeatedly matched until none of the patterns are applicable.
For example, the following routine uses a match while
statement
to traverse to the leftmost leaf.
template <class T> Tree<T> left_most_leaf(Tree<T> tree) { match while (tree) { case node(t,_,_): tree = t; } return tree; }
matchscan
variant of match can be used to
perform string matching on a stream. For example, a simple lexical
scanner can be written as follows.
int lexer (LexerBuffer& in) { matchscan while (in) { /if/: { return IF; } | /else/: { return ELSE; } | /while/: { return WHILE; } | /for/: { return FOR; } | /break/: { return BREAK; } | /[0-9]+/: { return INTEGER; } | /[a-zA-Z_][a-zA-Z_0-9]*/: { return IDENTIFIER; } | /[ \t]+/: { /* skip spaces */ } | ... // other rules } }