Generating C++ code from an SPL expression tree
An SPL expression tree represents the SPL
expression for a parameter or output expression in a form that can
be easily traversed in a C++ primitive operator. To use SPL expression
trees, the context of the primitive operator must include an <splExpressionTree
[param="true|false"] [output="true|false"] [cppCode="true|false"]/>
element.
Each node in an SPL expression tree can be examined to determine
the SPL type, the expression kind, and the C++ code for the node (if cppCode="true"
is specified).
For each expression kind, the associated information can be returned.
An example is the right side and left side expressions for a binary
operator, or the identifier in an identifier expression.
A subclass of ExpressionTreeVisitor (ExpressionTreeCppGenVisitor
)
is provided to walk the SPL expression tree and use the cppCode
fields
to regenerate the C++ code. To use ExpressionTreeCppGenVisitor
,
the SPL expression tree must be created with <splExpressionTreeMode
cppCode="true">
in the operator model for the primitive
operator. This code causes the generated C++ code for the SPL expression
to be placed in the SPL expression tree in a form that can be used
to generate code.
my $g = SPL::Operator::Instance::ExpressionTreeCppGenVisitor->new();
$g->visit ($expn->getSPLExpressionTree())
my $cppCode = $g->getCppCode();
# $cppCode contains a C++ expression that will evaluate to the expression.
To generate C++ code, replacing references to custom output
functions, see the following code:package Gen;
use base qw(SPL::Operator::Instance::ExpressionTreeCppGenVisitor);
sub visit_CallExpression($$)
{
my ($self, $expn) = @_;
my $fcnName = $expn->getFunctionName();
if ($fcnName =~ /^MatchRegex::(.*)/) {
$fcnName = $1;
if ($fcnName eq 'Count') {
$self->append('(CEP$COUNT+pmatch._Count)');
} elsif ($fcnName eq "Any") {
# gen different code here
}
return;
}
$self->SUPER::visit_CallExpression($expn);
}
The call $self->append(string)
is used
to generate the code to represent the expression. The generated code
must have the same C++ type as the replaced code. To parse a subexpression,
you can use: my $subExpn = $self->new();
$subExpn->visit($a);
$self->append($subExpn->getCppCode());