Author: pgmjsd Date: 2006-04-11 07:57:40 -0400 (Tue, 11 Apr 2006) New Revision: 9741 Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/HqlResolverASTFactory.java branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/StatementNode.java Modified: branches/HQL_ANTLR_2/Hibernate3/grammar/hql-resolve.g branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/HqlResolver.java branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/HqlResolverTest.java Log: Added a node factory to the new tree parser. Added simple context push and pop actions. Modified: branches/HQL_ANTLR_2/Hibernate3/grammar/hql-resolve.g =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/grammar/hql-resolve.g 2006-04-07 17:55:45 UTC (rev 9740) +++ branches/HQL_ANTLR_2/Hibernate3/grammar/hql-resolve.g 2006-04-11 11:57:40 UTC (rev 9741) @@ -3,6 +3,7 @@ // $Id:$ package org.hibernate.hql.antlr; +import java.util.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; } @@ -38,6 +39,35 @@ // -- Declarations -- { private static Log log = LogFactory.getLog( HqlBaseResolver.class ); + + private int level = 0; + private List inputContext = new ArrayList(); + private List outputContext = new ArrayList(); + + protected void pushContext(AST outputAst,AST inputAst) { + level++; + inputContext.add(inputAst); + outputContext.add(outputAst); + if (log.isDebugEnabled()) { + log.debug("Pushed context: level = " + level + " input is " + inputAst.toStringTree()); + } + } + + protected void popContext() { + level--; + AST n = (AST)inputContext.remove(inputContext.size() - 1); + outputContext.remove(outputContext.size() - 1); + if (log.isDebugEnabled()) { + log.debug("Popped context: level = " + level + " input was " + n.toStringTree()); + } + } + + protected AST getCurrentContext(boolean input) { + return (AST)((input) ? inputContext.get(inputContext.size() - 1) + : outputContext.get(outputContext.size() - 1)); + } + + protected int getLevel() { return level; } } // The main statement rule. @@ -52,15 +82,18 @@ ; updateStatement - : #(UPDATE (VERSIONED)? fromClause setClause (whereClause)? ) + : #(UPDATE (VERSIONED)? fromClause setClause (whereClause)? + { popContext(); } ) ; deleteStatement - : #(DELETE fromClause (whereClause)? ) + : #(DELETE fromClause (whereClause)? + { popContext(); } ) ; insertStatement - : #(INSERT intoClause query ) + : #(INSERT intoClause query + { popContext(); } ) ; query @@ -73,6 +106,7 @@ (whereClause)? (groupClause)? (orderClause)? + { popContext(); } ) ; @@ -83,11 +117,29 @@ // -- Language sub-elements -- fromClause - : #(FROM (subtree)* ) + : #(f:FROM { pushContext(#fromClause,f); } ( range | join | filter ) * ) ; +range + : #(RANGE path (ALIAS)? (FETCH)? ) + ; + +join + : #(JOIN (joinType )? (FETCH)? propertyRef (ALIAS)? (FETCH)? (WITH)? ) + ; + +joinType + : ( (LEFT | RIGHT) (OUTER)? ) + | FULL + | INNER + ; + +filter + : fe:FILTER_ENTITY a:ALIAS + ; + intoClause - : #(INTO (subtree)* ) + : #(i:INTO { pushContext(#intoClause,i); } (subtree)* ) ; whereClause @@ -106,6 +158,30 @@ : #(SET (subtree)* ) ; + +propertyRef + : #(DOT propertyRef propertyName ) + | identifier + ; + +propertyName + : identifier + | CLASS + | ELEMENTS + | INDICES + ; + +// Matches a path and returns the normalized string for the path (usually +// fully qualified a class name). +path + : identifier + | #(DOT path identifier) + ; + +identifier + : (IDENT | WEIRD_IDENT) + ; + // General subtree. Matches anything, copies the tree verbatim. subtree : #(. (subtree)*) Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/HqlResolver.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/HqlResolver.java 2006-04-07 17:55:45 UTC (rev 9740) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/HqlResolver.java 2006-04-11 11:57:40 UTC (rev 9741) @@ -11,6 +11,6 @@ public class HqlResolver extends HqlBaseResolver { public HqlResolver() { super(); - setASTFactory(new HqlASTFactory()); // Create nodes that track line and column number. + setASTFactory(new HqlResolverASTFactory()); // Create nodes that track line and column number. } } Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/HqlResolverASTFactory.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/HqlResolverASTFactory.java 2006-04-07 17:55:45 UTC (rev 9740) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/HqlResolverASTFactory.java 2006-04-11 11:57:40 UTC (rev 9741) @@ -0,0 +1,24 @@ +package org.hibernate.hql.ast; + +import org.hibernate.hql.antlr.HqlRTokenTypes; +import org.hibernate.hql.ast.tree.StatementNode; + +/** + * AST factory for the resolver phase. + * <br>User: Joshua Davis + * Date: Apr 3, 2006 + * Time: 7:58:16 AM + */ +public class HqlResolverASTFactory extends HqlASTFactory implements HqlRTokenTypes { + public Class getASTNodeType(int tokenType) { + // Statement nodes: + switch (tokenType) { + case QUERY : + case UPDATE: + case DELETE: + case INSERT: + return StatementNode.class; + } + return super.getASTNodeType(tokenType); + } +} Added: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/StatementNode.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/StatementNode.java 2006-04-07 17:55:45 UTC (rev 9740) +++ branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/StatementNode.java 2006-04-11 11:57:40 UTC (rev 9741) @@ -0,0 +1,10 @@ +package org.hibernate.hql.ast.tree; + +/** + * Represents a statement (SELECT, UPDATE, INSERT, DELETE) in the resolved HQL tree. + * <br>User: Joshua Davis + * Date: Apr 3, 2006 + * Time: 8:00:55 AM + */ +public class StatementNode extends Node { +} Modified: branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/HqlResolverTest.java =================================================================== --- branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/HqlResolverTest.java 2006-04-07 17:55:45 UTC (rev 9740) +++ branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/HqlResolverTest.java 2006-04-11 11:57:40 UTC (rev 9741) @@ -1,19 +1,16 @@ package org.hibernate.test.hql; +import antlr.RecognitionException; +import antlr.TokenStreamException; +import antlr.collections.AST; +import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import junit.framework.Test; -import antlr.collections.AST; -import antlr.RecognitionException; -import antlr.TokenStreamException; +import org.hibernate.hql.antlr.HqlRTokenTypes; +import org.hibernate.hql.ast.HqlResolver; +import org.hibernate.hql.ast.tree.StatementNode; import org.hibernate.hql.ast.util.ASTPrinter; -import org.hibernate.hql.ast.HqlParser; -import org.hibernate.hql.ast.HqlResolver; -import org.hibernate.hql.antlr.HqlRTokenTypes; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - /** * Tests the new HQL resolver phase. * <br>User: Joshua Davis @@ -30,13 +27,21 @@ public void testSimpleHql() throws Exception { // First, get an AST by parsing some HQL text. - AST hqlAst = HqlParserTest.doParse("from Foo f, Bar b where f.x.id = b.id",false); + AST ast = resolve("from Animal"); + // Assert: + // * The root node should be a statement. + assertTrue(ast instanceof StatementNode); + } + + private AST resolve(String hql) throws RecognitionException, TokenStreamException { + AST hqlAst = HqlParserTest.doParse(hql,false); // Now, pass it though the resolver phase, which yeilds // a processed HQL AST. HqlResolver resolver = new HqlResolver(); resolver.statement(hqlAst); AST resolvedHql = resolver.getAST(); System.out.println(hqlrPrinter.showAsString(resolvedHql,"Resolved AST : " + resolvedHql.toStringTree() + "" )); + return resolvedHql; } public static Test suite() { |