[antlr-interest] Custom ASTLabelType - setParent called with Null?

Jeremy Long jeremy.long at gmail.com
Sat Oct 15 13:23:19 PDT 2011


Hello,

I'm still relatively new to antlr, but basically I'm trying to generate an
AST and auto-populate a Neo4j Graph. My initial thought was to use a custom
ASTLabelType with my object over-riding the setParent method of the
CommonTree to build the relationship. However, on a very simple grammar
(Expr.g) parsing the input of  "1+2\n" of the 10 calls to setParent, 6 of
the calls where passed a null token?  Any thoughts on this?

The grammar, extended commonTree, and test case are below (however, none of
this will run as the overall project is bigger than this one piece).

Thanks in advance if anyone can clue me into why there are so many calls to
setParent passing a null token in.

--Jeremy



//////////////////////Eval Grammar

grammar Eval;

options {
ASTLabelType=BaseModelNode;
output = AST;
}

@header {

package org.sangine.translator.antlr3.generated;

import org.sangine.translator.antlr3.model.BaseModelNode;

}
@lexer::header {
package org.sangine.translator.antlr3.generated;

import org.sangine.translator.antlr3.model.BaseModelNode;
}

prog : stat+
;

stat : expr NEWLINE
| ID '=' expr NEWLINE
| NEWLINE
;


expr
: multExpr (('+'|'-') multExpr)*
;
multExpr
: atom ('*' atom)*
;
atom
: INT
| ID
| '(' expr ')'
;

ID : ('a'..'z'|'A'..'Z')+;
INT : '0'..'9'+;
NEWLINE : '\r'?'\n';
WS : (' '|'\t'|'\n'|'\r')+ {skip();};

---------------------------------------------------

/////////////////////////////////////////BaseModelNode.java


/**
 *
 */
package org.sangine.translator.antlr3.model;

import org.antlr.runtime.Token;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.Tree;
import org.neo4j.graphdb.Node;
import org.sangine.model.ModelNode;
import org.sangine.model.ModelRelationshipType;
import org.sangine.store.ApplicationGraph;

/**
 * @author Jeremy
 *
 */
public class BaseModelNode extends CommonTree {

private final Node underlyingNode;
 protected Node getUnderlyingNode()
{
return underlyingNode;
}
 /**
 *
 */
public BaseModelNode(Node node)
{
this.underlyingNode = node;
}

/**
 *
 */
public BaseModelNode(BaseModelNode node)
{
this.underlyingNode = node.underlyingNode;
}
 /**
 * @param node
 */
public BaseModelNode(CommonTree node) {
super(node);
this.underlyingNode = ApplicationGraph.getInstance().createNode();
}

/**
 * @param t
 */
public BaseModelNode(Token t) {
super(t);
this.underlyingNode = ApplicationGraph.getInstance().createNode();
 if (t==null) {
System.err.println("token was null");
return;
}
System.err.println("token was NOT null");
this.underlyingNode.setProperty("text", t.getText());
this.underlyingNode.setProperty("linenumber", t.getLine());
this.underlyingNode.setProperty("offset", t.getCharPositionInLine());
}

public BaseModelNode()
{
this.underlyingNode = ApplicationGraph.getInstance().createNode();
}

 @Override
public void setParent(Tree t) {
if (t==null) return;
this.parent = (CommonTree) t;
BaseModelNode parent = (BaseModelNode) t;
parent.underlyingNode.createRelationshipTo(this.underlyingNode,
ModelRelationshipType.NEXT);
}
 @Override
public int hashCode()
{
    return underlyingNode.hashCode();
}

@Override
public boolean equals( Object o )
{
    return o instanceof BaseModelNode &&
            underlyingNode.equals( ( (BaseModelNode)o ).getUnderlyingNode()
);
}

@Override
public String toString()
{
    return "BaseModelNode[]";
}

}

/////////////////////////////////////////////////////////// test code

package org.sangine;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.neo4j.graphdb.Transaction;
import org.sangine.store.ApplicationGraph;
import org.sangine.translator.antlr3.ModelTreeAdaptor;
import org.sangine.translator.antlr3.generated.EvalLexer;
import org.sangine.translator.antlr3.generated.EvalParser;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class EvalTest
    extends TestCase
{

public EvalTest( String testName )
    {
        super( testName );
    }

    public static Test suite()
    {
        return new TestSuite( EvalTest.class );
    }

    public void testApp()
    {
    ApplicationGraph.loadOrCreateDB("evaldb");

    Transaction tx =
ApplicationGraph.getInstance().getGraphDatabaseService().beginTx();

    String java = "1+2";

    ANTLRStringStream input = null;
input = new org.antlr.runtime.ANTLRStringStream(java);


EvalLexer lexer = new EvalLexer(input);


    CommonTokenStream tokens = new CommonTokenStream(lexer);

    ModelTreeAdaptor adaptor = new ModelTreeAdaptor();

    EvalParser parser = new EvalParser(tokens);
    parser.setTreeAdaptor(adaptor);

    EvalParser.stat_return cu = null;

    try {
cu = parser.stat();
tx.success();
assertTrue( true );
} catch (RecognitionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
assertTrue( false );
}
    finally {
    tx.finish();
    ApplicationGraph.close();
    }
    }
}


More information about the antlr-interest mailing list