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
}
}