Menu

INodeAdapter

Tom Harwood

Building a Custom INodeAdapter

An INodeAdapter implementation allows JBurg to work with your AST/i-node class.
The logic in JBurg's core works with an abstract i-node model; the INodeAdapter
translates that abstract model into platform-specific code that calls the correct
methods, or accesses the correct fields, in your i-node class.

INodeAdapter examples

Antlr3JavaAdapter

The JBurg distribution includes several INodeAdapter implementations. The Antlr3JavaAdapter implementation is shown below.


package jburg.burg.inode;

/*
* The Antlr3JavaAdapter is called by the JBurg code generator as it
* generates the BURM; the adapter translates implementation and target
* agnostic operations into code snippets appropriate for the ANTLR3
* Tree class.
/
public class Antlr3JavaAdapter implements InodeAdapter {

/**  The fully qualified name of the AST. */
public static final String s_iNodeType = "org.antlr.runtime.tree.Tree";

/**
 * Is this the correct INodeAdapter for the INodeType in the specification?
 * @param iNodeClass the qualified name of the AST/inode class being processed.
 * @return true if iNodeClass matches the ANTLR3 class name.
 */
public boolean accept(String iNodeClass) {
    return iNodeClass.equals(s_iNodeType);
}

/**
 * Generate a call to get the number of children a node has (its arity).
 * @param node an expression that will generate a path to the node.
 * @param emitter the target-specific code emitter.
 * @return a code snippet that calls node.getChildCount()
 */
public String genGetArity(String node, jburg.emitter.EmitLang emitter) {
    return emitter.genCallMethod(node, "getChildCount");
}

/**
 * Generate a call to get the n'th child of a node.
 * @param node an expression that will generate a path to the node.
 * @param index an expression that computes the index of the desired child.
 * @param emitter the target-specific code emitter.
 * @return a code snippet that calls node.getChild(index)
 */
public String genGetNthChild( String node, String index, jburg.emitter.EmitLang emitter) {
    return emitter.genCallMethod( node, "getChild", index );
}

/**
 * Generate a call to get the operator (the type) of a node.
 * @param node an expression that will generate a path to the node.
 * @param emitter the target-specific code emitter.
 * @return a code snippet that calls node.getType()
 */
public String genGetOperator( String node, jburg.emitter.EmitLang emitter) {
    return emitter.genCallMethod(node, "getType");
}

}

Falcon's IASNodeAdapter

Falcon's AST is quite complex, and the logic to access it is contained in static methods of Falcon's SemanticUtils utility class. This INodeAdapter generates calls to the static methods and passes in the node path:

public String genGetArity(String node_path, EmitLang emitter)
{
    return emitter.genCallMethod("SemanticUtils", "getChildCount", new String[] { node_path } );
}

INodeAdapter2

INodeAdapter2 has proved not as useful as hoped; in situations where the tree shape is so complex that a simple method call cannot return the correct result, we recommend using a static method and passing in the node path, as Falcon does. The resulting Java code is more maintainable than complex snippets generated on the fly.


Related

Wiki: DirectivesGuide

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.