JBurg specifications commonly take the file extension .jburg, e.g., tl1.jburg
.
The sections must be supplied in order, but within a section, the directives, rules, and cost functions may be written in any order. Comments may appear anywhere in the specification.
The required directives supply the Java class types of the BURM's input and output.
EBNF | "INodeType" inode_type:multipart_identifier SEMI |
---|---|
Usage |
|
Example |
|
EBNF | "ReturnType" return_type:multipart_identifier SEMI |
---|---|
Usage |
|
Example directive | ReturnType InstructionList; |
Example action | return new InstructionList ( new LDC ( cp.addString( "Hello world" ) ) ); |
EBNF | "BURMProperty" property_type:multipart_identifier property_name:IDENTIFIER SEMI |
---|---|
Usage |
|
Example JBurg directive | BURMProperty org.apache.bcel.generic.ClassGen classGen; |
Example code that sets the property |
|
EBNF | "header" { Java code } |
---|---|
Usage |
|
See also |
|
Example |
|
EBNF | "implements" implements_interface_name:multipart_identifier SEMI |
---|---|
Usage |
|
Example |
|
EBNF | "package" package_name:multipart_identifier SEMI |
---|---|
Usage |
|
See also | Header directive. The package name can also be coded into the header block; recommended practice is to use the Package directive, in case future versions of JBurg learn specialized processing procedures for a specific package. |
Example |
|
Each rule produces a goal. A goal is similar to a reduction in a parser generator, in reverse: a successful goal replaces the input AST with an output object. In the case of a code generator, the output is usually a code fragment, e.g., a BCEL InstructionList or an ABC InstructionList.
Each rule is also associated with a cost. In most cases, a cost is a simple integer; it can also be computed via a function, with the AST as a parameter.
EBNF | IDENTIFIER EQUALS operator_specification cost_specification { Java code } |
---|---|
Usage | This rule reduces an AST node of a particular kind (NODE_KIND), with either no, one, or two subgoals. The subgoals are similar to non-terminals in a parse generator. |
Example 1 | int = PLUS(int i1, int i2): 1 { /* code to add two int values */ }
This pattern-matching rule produces an int, given a PLUS node with two children that can both satisfy the "int" goal. |
EBNF | IDENTIFIER EQUALS IDENTIFER LPAREN VOID RPAREN { Java code } |
---|---|
Usage | These are trivial pattern rules, where the pattern consists solely of the leaf. |
Example |
int = INTEGER_LITERAL(void) { code to implement integer literal }
|
EBNF | IDENTIFIER EQUALS IDENTIFIER SEMI |
---|---|
Usage | Transformation rules allow the code generator to use one goal to satisfy another goal. |
Example |
numeric_value = int; |
This transformation tells the BURM that the "int" goal can satisfy the "numeric_value" goal. Since this is a simple transformation, the cost will be carried over from the int goal. |
EBNF | IDENTIFIER EQUALS IDENTIFIER cost_specification { Java code } |
---|---|
Usage |
This transformation rule also allows the code generator to use one goal to satisfy another, but specifies some additional processing that accomplishes the transformation. The cost spec should only consider the cost of the transformation code; the code generator will add in the cost of the original node. |
Example |
int = numeric_value : 1 { code to convert an arbitrary number to an int}
|
EBNF | IDENTIFIER LPAREN RPAREN { Java code } |
---|---|
Usage |
Cost functions are Java code that returns an int value. The value is used to compute the cost of a particular candidate reduction. The BURM searches for the lowest total cost sequence of reductions to rewrite an input subtree, so low values mean "good cost," higher values mean "less desirable." The cost function has a single implicit parameter, |
Example |
|