Author(s) |
Eric Faulhaber Greg Shah |
Date |
November 1, 2007 |
Access Control |
CONFIDENTIAL |
pattern
package is
to provide a processing engine which is applied against ASTs to detect
structural and data patterns, and to perform actions conditionally,
according to the needs of the user. Given a definition which
includes, at a high level:a + b = c
), which is a natural convention
for most people. It is possible to embed constants, variables, functions, and a variety of operators within these
expressions. An action typically utilizes one or more function
invocations within its expression, since an algebraic comparison in and
of itself does not invoke any behavior beyond simple evaluation to a
boolean result. A symbol
resolver is used to substitute runtime data for the constants,
variables, and function invocations in an expression. This data
may be extracted from the environment, from user-provided variables, or
from an AST.Event
Type |
Occurs |
Node
in Scope |
Notes |
<init-rules> | once for each tree, before any
other rule executes |
tree root |
Useful for initialization logic,
especially for variables that are unique per-tree (a single instance is
used to track state across an entire tree walk. |
<walk-rules> | once for each node, this is the
"primary" visit to the node |
the current node being visited |
Most logic is inserted in these
rules. Anything that does not depend upon the order of processing
children is usually placed here. |
<descent-rules> | when the tree walk descends from a parent to its first child (it occurs after the parent has gotten its <walk-rules> and before the child gets its <walk-rules>) | the parent node |
Very useful for implementing
scope-aware data structures (such as a stack). Scopes are
normally pushed (added) on descent. This never occurs for nodes that have no children. |
<next-child-rules> | when the tree walk moves between siblings (it occurs after the current [left] sibling has gotten its <walk-rules>, and after all processing is complete for that left sibling's descendants and before the next [right] sibling gets its <walk-rules>) | the parent node | In rule-sets that convert a tree
to a human readable form, these rules
are highly useful for implementing differential processing based on the
index of the child being processed (the "nextChildIndex"). For
example, in converting the tree form of a Java method call
(assume that the first child is the Object instance upon which the
method is called) into a
source code version, one might need to output a ".methodName(" after
the first child has been processed but before all other children are
processed. This is generally useful in any case where processing needs to occur between the processing of any two children. This never occurs for nodes that have no children. |
<ascent-rules> | when the tree walk ascends from the last child to its parent (it occurs after the last child has gotten its <walk-rules> and after all processing is complete for the last child's descendants) | the parent node | Very useful for implementing
scope-aware data structures (such as a stack). Scopes are
normally popped (deleted) on ascent. In rule-sets that convert a tree to a human readable form, these rules are highly useful for closing processing after all children are processed. For example, in converting the tree form of a function call (assume that the children represent function call parameters) into a source code version, one might need to output a closing ")" after all parameters are emitted. This never occurs for nodes that have no children. |
<post-rules> | once for each tree, after all other rules have executed | tree root | Useful for termination logic, especially for implementing any filesystem or database persistence that is done on a per-tree basis. |
Rule
is the implementation
of the conditional rule.AstSymbolResolver
is the implementation of the symbol
resolver.RuleSet
is the
implementation of the ruleset.PatternEngine
is
the implementation of the pattern
engine, and also manages the ruleset pipeline.PatternWorker
is
the interface which all pattern worker
objects implement. AbstractPatternWorker
is a partial implementation of this interface to simplify the creation
of concrete pattern worker implementations.xml
.
Ruleset profile documents always have a filename extension of rules
.
A ConfigLoader
object is
responsible for parsing the pipeline profile document, for resolving
any references to external ruleset profile documents, and for
configuring the pattern engine using all of the information extracted
from the resulting network of documents..xml
file name extension; a ruleset
profile must use the .rules
file name
extension. The ruleset profile file format is a subset of the
pipeline profile format. The following describes the grammar:Name |
Scope |
Num |
Children |
Description |
|||||||||||||||
cfg |
P |
1 |
ast-spec |
Outermost containing element
(root) of
the pipeline profile document. No attributes are defined for this element. |
|||||||||||||||
ast-spec |
P |
0+ |
none |
Defines a directory and file
specification used to find a list of either (a) persisted AST files to
process; or (b) root node entries in a call graph. If no
such element is provided, such a specification must be provided at the
pattern engine command line; otherwise, no processing will occur.
|
|||||||||||||||
worker |
P |
0+ |
none |
Defines a PatternWorker
implementation for the pattern engine to load for a specialized
task. Several pattern workers are loaded by default to provide
standard services. This element gives the user the opportunity to
load additional worker objects, to provide additional variables and/or
user functions for a particular purpose.
|
|||||||||||||||
include |
P/R |
0+ |
none |
Loads a function library from
the given rules filename. Whether this filename is
unqualified or partially qualified, each segment in the pattern path is
searched for the first file that matches. That file is loaded and any
public func-library element in that file is made accessible.
|
|||||||||||||||
func-library |
P/R |
0+ |
expression
|
Provides a set of named
expressions or functions which can be used in the current rule file or
imported into an external rule file for use.
|
|||||||||||||||
expression |
P/R |
1+ |
none |
Use of this element is discouraged. This should be considered deprecated. Contains a single expression which is evaluated unconditionally. This is similar to an action element, except:
|
|||||||||||||||
function |
P/R | 1+ | parameter |
Defines a named block of logic that:
By default, if no return element is defined, the return value is the same as the last executed expression in the function (whether this expression is directly specified in the function element's text or whether this is a contained rule, action, expression or while element). Variables that are in enclosing scopes can be accessed but this is discouraged. The function element is considered a new scope and can hide variables which have the same name in enclosing scopes. Some problems to note:
|
|||||||||||||||
variable |
P/R |
0+ |
none |
Declares a user variable to use
in rule expressions. Variables are global across rulesets if
defined in the scope of a pipeline profile. Variables are local
to an individual ruleset if defined within the scope of a ruleset
profile.
|
|||||||||||||||
parameter |
P/R | 0+ | none | Declares a parameter to use
in a named function. This is equivalent to a local variable,
except the value is assigned by the caller in the parameter list (2nd
and subsequent parameters to the execLib() and evalLib() functions).
Note that the order, type and number of the parameters in the
function definition must match those passed in the function invocation.
|
|||||||||||||||
return |
P/R | 0 or 1 | none | Declares a local variable, whose value will be returned to
the caller of the function when the function completes. This also
determines the type of the function's return value.
|
|||||||||||||||
rule-set |
P/R |
1+ |
expr-library
|
Defines a set of rules and
resources used by the pattern engine to process the information stored
within an AST. Rulesets which are tightly coupled to the purpose
of the pipeline's task may be defined inline, within the main pipeline
profile document. Alternatively, more general purpose, reusable
rulesets may be defined individually, within their own .rules
files.If defined within a .rules file, this element is the
outermost containing element (root) of the profile document (rather than having an outermost cfg element).If defined within a .xml file (the master profile
document), this element can either define an entire ruleset inline, or
refer to an external ruleset defined within a .rules
file. If the element contains the name attribute
(see below), it refers to an external ruleset profile. Otherwise,
it is expected that an inline ruleset definition follows the opening
tag.This element defines a new scope for the purpose of resource access such as variables. Resources in enclosing scopes can be accessed but enclosing scopes cannot access resources defined within this element.
|
|||||||||||||||
init-rules |
P/R | 0-1 | rule |
A list of rules to run as
initialization processing, either globally
across all rulesets in the pipeline, or locally, within an individual
ruleset. If defined within the pipeline profile document, the
init
rules are global; if defined within a ruleset profile document,
the
init rules are local to that ruleset. Global init rules are applied once per pipeline, after pattern workers are initialized, but before any individual rulesets are processed. No AST is in scope for purposes of rule expression processing when the global init rule list is applied. Local init rules are applied each time a ruleset is applied against an AST, before any of the ruleset's walk rules are applied. The root node of the AST being processed by the current ruleset is in scope for purposes of rule expression processing when a local init rule list is applied. So, any rule expressions which refer to properties of an AST will use the root AST to resolve AST property variables or to apply changes against the AST. No attributes are defined for this element. |
|||||||||||||||
descent-rules |
P/R |
0-1 |
rule |
||||||||||||||||
walk-rules |
R* |
0-1 |
rule |
A list of rules to apply against
an iteration of AST nodes. Depending upon the value of the input
attribute of the enclosing rule-set element, this list of
rules is either applied against every AST node in the current AST
hierarchy, or against only those AST nodes included in the filtered
view defined by the previous ruleset in the pipeline.No attributes are defined for this element. |
|||||||||||||||
ascent-rules |
P/R |
0-1 |
rule |
||||||||||||||||
post-rules |
P/R |
0-1 |
rule |
A list of rules to run as
termination processing, either globally
across all rulesets in the pipeline, or locally, within an individual
ruleset. If defined within the pipeline profile document, the
post
rules are global; if defined within a ruleset profile document,
the post rules are local to that ruleset. Global post rules are applied once per pipeline, after all individual rulesets have been processed, but before pattern worker termination processing takes place. No AST is in scope for purposes of rule expression processing when the global post rule list is applied. Local post rules are applied each time a ruleset is applied against an AST, after any of the ruleset's walk rules are applied. The root node of the AST being processed by the current ruleset is in scope for purposes of rule expression processing when a local post rule list is applied. So, any rule expressions which refer to properties of an AST will use the root AST to resolve AST property variables or to apply changes against the AST. No attributes are defined for this element. |
|||||||||||||||
rule |
R* |
1+ |
rule |
Defines a logical condition and
an optional list of actions to perform if that condition is met or not
met. The condition and actions are each defined as logical
expressions. They may contain system/AST variables (exposed by
pattern worker objects) or global or local user variables defined using
the variable element.CDATA may be used to contain the condition however, it is common to put the condition directly in the element text. Note that a rule with no contained elements is the functional equivalent of an action. This element defines a new scope for the purpose of resource access such as variables. Resources in enclosing scopes can be accessed but enclosing scopes cannot access resources defined within this element.
|
|||||||||||||||
while |
R* |
0+ |
rule while action |
This is a looping
construct. While the logical condition is true, the optional list
of rules, whiles and actions are performed. Any contained
elements which use the on="false" attribute are never executed as the
concept of a while loop inherently precludes this. The condition
is defined as a logical
expression. They may contain system/AST variables (exposed by
pattern worker objects) or global or local user variables defined using
the variable element.
|
|||||||||||||||
action |
R* |
0+ |
none
|
Defines an action to perform in
the event the enclosing rule's condition is met or not met.
|