All Downloads are FREE. Search and download functionalities are using the official Maven repository.

it.twenfir.antlr.ast.AstHelper Maven / Gradle / Ivy

There is a newer version: 0.1.3
Show newest version
package it.twenfir.antlr.ast;

import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
import org.antlr.v4.runtime.tree.RuleNode;

import it.twenfir.antlr.exception.AstException;

/**
 * Provide methods to help building AST's 
 */
public class AstHelper {

	/** 
	 * Visit children of an ANTLR parse tree node and add them as children of the current AST node.
	 * Assumes that the default implementation of visit returns null making it possible
	 * to override it only for interesting nodes.
	 * 
	 * @param  	  the visitor's type
	 * @param visitor the visitor implementation
	 * @param node    the current parse tree node 
	 * @param parent  the AST node to which children will be added
	 */
	public static > void visitChildren(V visitor, RuleNode node, AstNode parent) {
		int n = node.getChildCount();
		for (int i=0; ivisit returns null making it possible
	 * to override it only for interesting nodes.
	 * 
	 * @param  	  the visitor's type
	 * @param visitor the visitor implementation
	 * @param node    the current parse tree node 
	 * @return        the AST node corresponding to the current parse tree node
	 */
	public static > AstNode visitChild(V visitor, RuleNode node) {
		int n = node.getChildCount();
		if ( n > 1 ) {
			throw new AstException("Parse tree node has multiple children");
		}
		else if ( n == 1 ) {
			ParseTree c = node.getChild(0);
			AstNode child = c.accept(visitor);
			if ( child != null ) {
				return child;
			}
		} 
		return null;
	}

	/** 
	 * Create a Location instance from an ANTLR rule context.
	 * 
	 * @param context the current ANTLR context
	 * @return        the newly created instance
	 */
	public static Location location(ParserRuleContext context) {
        Token start = context.getStart();
        return new Location(start.getLine(), start.getCharPositionInLine(), start.getTokenIndex(), 
                context.getStop().getTokenIndex());
    }

	/**
	 * Alternative implementation for the default visit method of an AST listener that creates
	 * anonymous nodes when there is more than one descendant.
	 * 
	 * @param 	  the type of the visitor
	 * @param visitor the visitor instance
	 * @param ctx	  the current rule context
	 * @return		  the single descendant or a new anonymous node
	 */
	public static > AstNode visit(V visitor, ParserRuleContext ctx) {
		int n = ctx.getChildCount();
		if ( n == 1 ) {
			ParseTree c = ctx.getChild(0);
			return c.accept(visitor);
		}
		else {
			Location location = location(ctx);
			Node node = new Node(location);
			for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy