Download phc Documentation

Transcript
Chapter 5. Restructuring the Tree
explains exactly how the signatures for the pre and post methods are derived, but in most cases they
are what you’d expect. The easiest way to check is to simply look them up in <AST_transform.h>.
The Implementation
We wanted to get rid of useless concatenation operators. To be precise, if the binary operator is the
concatenation operator, and the left operand is the empty string, we want to replace the node by the right
operand; similarly, if the right operand is the empty string, we want to replace the operator by its left
operand. Here’s the full transform:
class Remove_concat_null : public Transform
{
public:
Expr* post_bin_op(Bin_op* in)
{
STRING* empty = new STRING(new String(""));
Wildcard<Expr>* wildcard = new Wildcard<Expr>;
// Replace with right operand if left operand is the empty string
if(in->match(new Bin_op(empty, wildcard, ".")))
return wildcard->value;
// Replace with left operand if right operand is the empty string
if(in->match(new Bin_op(wildcard, empty, ".")))
return wildcard->value;
return in;
}
}
We already explained what match does in Chapter 4, but we have not yet explained the use of
wildcards. If you are using a wildcard (WILDCARD) in a pattern passed to match, match will not take
that subtree into account. Thus,
if(in->match(new Bin_op(empty, WILDCARD, ".")))
can be paraphrased as “is in a binary operator with the empty string as the left operand and "." as the
operator (I don’t care about the right operand)?“ If the match succeeded, you can find out which
expression was matched by the wildcard by accessing wildcard->value.
Running Transformations
Recall from the previous two tutorials that visitors are run with a call to visit:
extern "C" void run_ast (PHP_script* in, Pass_manager* pm, String* option)
{
SomeVisitor visitor;
in->visit(&visitor);
19