StartOfFinder.java
package edu.udel.cis.vsl.tass.ast.impl;
import edu.udel.cis.vsl.tass.ast.IF.ASTFactoryIF;
import edu.udel.cis.vsl.tass.ast.IF.ASTNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.ASTTransformerIF;
import edu.udel.cis.vsl.tass.ast.IF.AbstractSyntaxTreeIF;
import edu.udel.cis.vsl.tass.ast.IF.expression.OperatorNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.expression.VariableReferenceNodeIF;
import edu.udel.cis.vsl.tass.ast.IF.type.ArrayTypeNodeIF;
import edu.udel.cis.vsl.tass.model.IF.SyntaxException;
/**
* This class finds instances where arrays are referenced without a subscript
* expression and replaces each reference with a StartOfNodeIF.
*
* @author Timothy Zirkel (zirkel)
*
*/
public class StartOfFinder implements ASTTransformerIF {
ASTFactoryIF factory;
@Override
public void transform(AbstractSyntaxTreeIF ast) throws SyntaxException {
factory = ast.factory();
traverse(ast.rootNode());
}
/**
* This method recursively traverses the AST and checks whether each node is
* an operator that might have an array reference that needs to be replaced
* with a StartOfNode. If it is, the expression is checked and the
* StartOfNode inserted if necessary.
*/
private void traverse(ASTNodeIF node) {
if (node instanceof OperatorNodeIF) {
checkAndFix((OperatorNodeIF) node);
}
for (int i = 0; i < node.numChildren(); i++) {
if (node.child(i) != null) {
traverse(node.child(i));
}
}
}
/**
* Takes an operator node, checks if any of the operands are references to
* arrays, and replaces each such reference with a StartOfNode.
*/
private void checkAndFix(OperatorNodeIF node) {
for (int i = 0; i < node.numChildren(); i++) {
if (node.getArgument(i) instanceof VariableReferenceNodeIF
&& ((VariableReferenceNodeIF) node.getArgument(i))
.referent().type() instanceof ArrayTypeNodeIF) {
node.setArgument(i, factory
.startOfNode((VariableReferenceNodeIF) node
.getArgument(i)));
}
}
}
@Override
public String name() {
return "StartOfFinder";
}
}