| | */ |
| | public class Parser extends QueryBaseListener { |
| | + private static int INDENT = 2; |
| | + |
| | private RXM rxm; |
| | |
| | /** Used to convert linear map to hierarchical form. */ |
| | private List<String> statements = new ArrayList<String>(); |
| | |
| | /** Tracks the SQL statement insertion point. */ |
| | private int depth = 0; |
| | |
| | - private Tree<ParserRuleContext> tree; |
| | + /** The tree constructed while walking the <b>rxm</b>. */ |
| | + private Tree<ParserRuleContext> queryTree; |
| | + |
| | + /** Current context within queryTree. */ |
| | + private Tree<ParserRuleContext> contextTree; |
| | |
| | /** |
| | - * Creates a Parser instance that parses a given <b>rxm</b> string. |
| | + * Creates a Parser instance that parses a given <b>rxm</b>. |
| | * |
| | * @param rxm The <b>rxm</b> instance responsible for receiving information |
 |
| | @Override |
| | public synchronized void enterQuery( QueryParser.QueryContext ctx ) { |
| | - setTree( new Tree<ParserRuleContext>( ctx ) ); |
| | + setQueryTree( createTree( ctx ) ); |
| | } |
| | |
| | @Override |
| | public synchronized void enterRoot( QueryParser.RootContext ctx ) { |
| | - String root = ctx.getChild(2).getText(); |
| | - |
| | - push( "XMLROOT(" ); |
| | - push( String.format( "XMLELEMENT( NAME \"%s\"", root ) ); |
| | + setContextTree( getQueryTree().addLeaf( ctx ) ); |
| | + } |
| | |
| | - decreaseDepth(); |
| | - push( ")" ); |
| | - decreaseDepth(); |
| | - push( ", VERSION '1.0', STANDALONE YES)" ); |
| | + @Override |
| | + public synchronized void enterTableMap( QueryParser.TableMapContext ctx ) { |
| | + setContextTree( getContextTree().addLeaf( ctx ) ); |
| | } |
| | |
| | @Override |
| | - public synchronized void enterMap( QueryParser.MapContext ctx ) { |
| | + public synchronized void enterColumnMap( QueryParser.ColumnMapContext ctx ) { |
| | + getContextTree().addLeaf( ctx ); |
| | } |
| | |
| | @Override |
| | - public synchronized void exitMap( QueryParser.MapContext ctx ) { |
| | + public synchronized void enterPop( QueryParser.PopContext ctx ) { |
| | + setContextTree( getContextTree().getParent() ); |
| | } |
| | |
| | @Override |
| | - public synchronized void enterElement( QueryParser.ElementContext ctx ) { |
| | + public synchronized void exitQuery( QueryParser.QueryContext ctx ) { |
| | + /* |
| | + push( "XMLROOT(" ); |
| | + push( String.format( "XMLELEMENT( NAME \"%s\"", root ) ); |
| | + |
| | + push( ")" ); |
| | + push( ", VERSION '1.0', STANDALONE YES)" ); |
| | + |
| | String s = String.format( "XMLELEMENT( \"%s\" AS %s )", |
| | ctx.getText(), "COLUMN" ); |
| | push( s ); |
| | - } |
| | - |
| | - @Override |
| | - public synchronized void enterAttribute( QueryParser.AttributeContext ctx ) { |
| | String s = String.format( "XMLATTRIBUTES( %s AS \"%s\" )", |
| | "COLUMN", ctx.getText().substring(1) ); |
| | push( s ); |
| | + */ |
| | + |
| | + System.out.println( toString() ); |
| | } |
| | |
| | + /** |
| | + * Performs a depth-first traversal to generate a printable string. |
| | + */ |
| | @Override |
| | - public synchronized void exitQuery( QueryParser.QueryContext ctx ) { |
| | - // Traverse the stack in order. |
| | - for( String s : getStatements() ) { |
| | - System.out.println( s ); |
| | - } |
| | + public String toString() { |
| | + return toString( getQueryTree().getLeaves().get(0), INDENT ); |
| | } |
| | |
| | - private void push( String s ) { |
| | - getStatements().add( getDepth() + "." + createIndent() + s ); |
| | - increaseDepth(); |
| | - } |
| | + /** |
| | + * Depth-first traversal. |
| | + */ |
| | + private String toString( Tree<ParserRuleContext> tree, int increment ) { |
| | + String s = indent( increment ) + tree.getPayload().getText(); |
| | |
| | - private String createIndent() { |
| | - String empty = CharBuffer.allocate( getDepth() * 2 ).toString(); |
| | - return empty.replace( '\0', ' ' ); |
| | - } |
| | + for( Tree<ParserRuleContext> child : tree.getLeaves() ) { |
| | + s += String.format( "%n%s", toString( child, increment + INDENT ) ); |
| | + } |
| | |
| | - private void increaseDepth() { |
| | - setDepth( getDepth() + 1 ); |
| | + return s; |
| | } |
| | |
| | - private void decreaseDepth() { |
| | - setDepth( getDepth() - 1 ); |
| | + private String indent( int spaces ) { |
| | + String empty = CharBuffer.allocate( spaces ).toString(); |
| | + return empty.replace( '\0', ' ' ); |
| | } |
| | |
 |
| | } |
| | |
| | - private void setDepth( int depth ) { |
| | - this.depth = depth; |
| | + private void setContextTree( Tree<ParserRuleContext> contextTree ) { |
| | + this.contextTree = contextTree; |
| | } |
| | |
| | - private int getDepth() { |
| | - return this.depth; |
| | + private Tree<ParserRuleContext> getContextTree() { |
| | + return this.contextTree; |
| | } |
| | |
| | - private void setTree( Tree<ParserRuleContext> tree ) { |
| | - this.tree = tree; |
| | + private void setQueryTree( Tree<ParserRuleContext> queryTree ) { |
| | + this.queryTree = queryTree; |
| | } |
| | |
| | - private Tree<ParserRuleContext> getTree() { |
| | - return this.tree; |
| | + private Tree<ParserRuleContext> getQueryTree() { |
| | + return this.queryTree; |
| | + } |
| | + |
| | + /** |
| | + * Creates a new tree with the given payload. |
| | + */ |
| | + private Tree<ParserRuleContext> createTree( ParserRuleContext payload ) { |
| | + return new Tree<ParserRuleContext>( payload ); |
| | } |
| | } |