Commits

Tim Vernum committed 0ba1b2a

Parser changes to support conversion

Comments (0)

Files changed (51)

 <!-- vim: set ft=ant ts=2 sts=2 expandtab shiftwidth=2  : -->
-<project name="syntactic"  default="all" basedir="."  xmlns:ivy="antlib:org.apache.ivy.ant" >
+<project name="syntactic-parser"  default="all" basedir="."  xmlns:ivy="antlib:org.apache.ivy.ant" >
 
   <property name="javacc.home" value="/Users/tim/Development/Libraries/javacc/javacc-5.0/"/>
 

parser/source/grammar/java.jjt

 
     public static Node processStdin()
     {
-        System.out.println("Java Parser Version 1.2:  Reading from standard input . . .");
         return process( new JavaParser(System.in) );
     }
 
     public static Node process(String file)
     {
-        System.out.println("Java Parser Version 1.2:  Reading from file " + file + " . . .");
         try 
         {
             return process(new JavaParser(new java.io.FileInputStream(file)));
         }
         catch (java.io.FileNotFoundException e)
         {
-            System.out.println("Java Parser Version 1.2:  File " + file + " not found.");
+            System.err.println("Java Parser Version 1.2:  File " + file + " not found.");
             return null;
         }
     }
         try
         {
             Node node = parser.CompilationUnit();
-            System.out.println("Java Parser Version 1.2:  Java program parsed successfully.");
             return node;
         }
         catch (ParseException e)
         {
-            System.out.println(e.getMessage());
-            System.out.println("Java Parser Version 1.2:  Encountered errors during parse.");
+            System.err.println(e.getMessage());
+            System.err.println("Java Parser Version 1.2:  Encountered errors during parse.");
             return null;
         }
     }
   "(" Type() ")" UnaryExpressionNotPlusMinus()
 }
 
-void PrimaryExpression() #void :
+void PrimaryExpression() :
 {}
 {
-    ( PrimaryPrefix() ( LOOKAHEAD(PrimarySuffix()) PrimarySuffix() )*  ) #PrimaryExpression(>1)
+    ( PrimaryPrefix() ( LOOKAHEAD(PrimarySuffix()) PrimarySuffix() )*  ) 
 }
 
 void PrimaryPrefix() #void:

parser/source/java/parser/org/adjective/syntactic/parser/BaseNode.java

 
 package org.adjective.syntactic.parser;
 
-import org.adjective.syntactic.parser.ast.ASTArraySuffixList;
-import org.adjective.syntactic.parser.ast.ASTIdentifier;
-import org.adjective.syntactic.parser.ast.Node;
-import org.adjective.syntactic.parser.ast.SimpleNode;
+import org.adjective.syntactic.parser.ast.*;
 import org.adjective.syntactic.parser.jj.Token;
 import org.adjective.syntactic.parser.util.ArrayType;
 import org.adjective.syntactic.parser.util.JavaType;
+import org.adjective.syntactic.parser.util.NodeType;
+import org.adjective.syntactic.parser.util.TypeNode;
 
-import java.util.Iterator;
-import java.util.NoSuchElementException;
+import java.util.*;
 
 /**
  * @author <a href="http://blog.adjective.org/">Tim Vernum</a>
  */
-public class BaseNode extends SimpleNode
+public class BaseNode extends SimpleNode implements NodeType
 {
-    public BaseNode(int i)
+    protected BaseNode(int i)
     {
         super(i);
     }
 
     private <T extends Node> T child(Class<T> type, boolean optional)
     {
-        for (BaseNode node : children())
+        for (NodeType node : children())
         {
             if (type.isInstance(node))
             {
             {
                 return new NodeIterator<T>(type, false);
             }
+
+            @Override
+            public String toString()
+            {
+                return "allChildren(" + type + ") {" + jjtGetNumChildren() + "}";
+            }
         };
     }
 
         return jjtGetNumChildren() == 0;
     }
 
-    public BaseNode getFirstChild()
+    protected BaseNode getFirstChild()
     {
         if (isEmpty())
         {
         return (BaseNode) jjtGetChild(0);
     }
 
-    public BaseNode getLastChild()
+    protected BaseNode getLastChild()
     {
         if (isEmpty())
         {
         return (BaseNode) jjtGetChild(jjtGetNumChildren() - 1);
     }
 
+    protected void appendChild(final Node node)
+    {
+        jjtAddChild(node, jjtGetNumChildren());
+    }
 
+    protected void appendChildren(final Node... nodes)
+    {
+        for (Node node : nodes)
+        {
+            appendChild(node);
+        }
+    }
+
+    @Override
     public boolean is(Class<? extends Node> nodeType)
     {
         return nodeType.isInstance(this);
     }
 
+    @Override
     public <T extends Node> T as(Class<T> nodeType)
     {
         if (is(nodeType))
         return builder.toString();
     }
 
-    public int countTokens(final int kind)
+    protected int countTokens(final int kind)
     {
         int count = 0;
         for (Token token : tokens())
         };
     }
 
+    protected void setChildren(final Node... elements)
+    {
+        // We run in reverse order to reduce the number of array allocations
+        for (int i = elements.length - 1; i >= 0; i--)
+        {
+            jjtAddChild(elements[i], i);
+        }
+    }
+
+    protected void setChildren(final Iterable<? extends Node> elements)
+    {
+        int i = 0;
+        for (Node element : elements)
+        {
+            jjtAddChild(element, i);
+            i++;
+        }
+    }
+
+    protected TypeNode makeTypeNode(final JavaType type)
+    {
+        TypeNode componentType;
+        switch (type.getBaseType())
+        {
+            case OBJECT:
+            case STRING_LITERAL:
+                componentType = new ASTClassOrInterfaceType(type.getParameterizedTypeName());
+                break;
+            case LAMBDA_LITERAL:
+                throw new IllegalArgumentException("Cannot create a type node for a lambda");
+            case VOID:
+                return new ASTVoidType();
+            default:
+                componentType = new ASTPrimitiveType(type.getBaseType());
+                break;
+        }
+        if (type.getArrayDepth() == 0)
+        {
+            return componentType;
+        }
+        else
+        {
+            return new ASTReferenceType(componentType, type.getArrayDepth());
+        }
+    }
+
+    protected Token makeToken(final int kind, final String image)
+    {
+        final Token token = new Token();
+        token.image = image;
+        token.kind = kind;
+        return token;
+    }
+
+    public <T extends Node> T findAncestor(final Class<T> type)
+    {
+        for (Node node = jjtGetParent(); node != null; node = node.jjtGetParent())
+        {
+            if (type.isInstance(node))
+            {
+                return type.cast(node);
+            }
+        }
+        return null;
+    }
+
+    public void replace(final Node node, final Collection<? extends Node> replacement)
+    {
+        List<Node> nodes = new ArrayList<Node>();
+        for (BaseNode child : children())
+        {
+            if (child == node)
+            {
+                nodes.addAll(replacement);
+            }
+            else
+            {
+                nodes.add(child);
+            }
+        }
+        jjtClearChildren();
+        setChildren(nodes);
+    }
+
     private class NodeIterator<T extends Node> implements Iterator<T>
     {
         private final Class<T> _type;
             _type = type;
             _skipNonMatching = skipNonMatching;
             _index = start - 1;
-            _stop = end;
+            _stop = Math.min(end, jjtGetNumChildren());
             advance();
         }
 
         private void advance()
         {
-            for (_index++; _index < _stop; _index++)
+            for (_index++; hasNext(); _index++)
             {
                 Node node = jjtGetChild(_index);
                 if (_type.isInstance(node) || !_skipNonMatching)
         @Override
         public boolean hasNext()
         {
-            return _index < jjtGetNumChildren();
+            return _index < _stop;
         }
 
         @Override
         public Token next()
         {
             Token tok = _next;
-            if(tok == null) {
+            if (tok == null)
+            {
                 throw new NoSuchElementException();
             }
-            if(_next == _last) {
+            if (_next == _last)
+            {
                 _next = null;
-            } else {
+            }
+            else
+            {
                 _next = _next.next;
             }
             return tok;

parser/source/java/parser/org/adjective/syntactic/parser/DefaultVisitor.java

+/*
+ * ------------------------------------------------------------------------
+ *  Copyright 2013 Tim Vernum
+ *  ------------------------------------------------------------------------
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  ------------------------------------------------------------------------
+ */
+package org.adjective.syntactic.parser;
+
+import org.adjective.syntactic.parser.ast.*;
+
+public class DefaultVisitor<R, T> implements JavaParserVisitor<R, T>
+{
+    @Override
+    public R visit(final SimpleNode node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTCompilationUnit node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTPackageDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTAnnotations node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTImports node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTImportDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTStaticImport node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTWildcardImport node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTTypes node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTModifiers node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTTypeDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTClassOrInterfaceDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTClassOrInterfaceKeyword node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTIdentifier node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTExtendsList node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTImplementsList node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTEnumDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTEnumBody node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTEnumConstants node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTEnumConstant node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTTypeParameters node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTTypeParameter node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTTypeBound node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTClassOrInterfaceBody node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTClassOrInterfaceBodyElement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMember node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTFieldDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTVariableDeclarator node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTArrayInitializer node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMethodDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMethodBody node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTArraySuffixList node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTArraySuffix node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTFormalParameters node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTFormalParameter node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTVariableModifiers node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTVarArgs node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTConstructorDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTConstructorBody node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTExplicitConstructorInvocation node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTInitializer node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTReferenceType node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTClassOrInterfaceType node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTParameterizedIdentifier node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTTypeArguments node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTTypeArgument node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTWildcardBounds node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTPrimitiveType node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTVoidType node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTQualifiedIdentifier node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTNameList node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTAssignmentOperator node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTTernaryExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTLogicalOrExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTLogicalAndExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTInclusiveOrExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTExclusiveOrExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTAndExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTEqualityExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTBinaryOperator node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTInstanceOfExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTRelationalExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTShiftExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTAdditiveExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMultiplicativeExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTUnaryExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTPrefixExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTUnaryOperator node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTPostfixExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTCastExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTPrimaryExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTSuperExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTBracketExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMemberSuffix node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMemberReference node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTNew node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTIntegerLiteral node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTFloatingPointLiteral node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTCharacterLiteral node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTStringLiteral node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTThis node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTSuper node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTClassReference node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTArrayIndex node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTBooleanLiteral node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTNullLiteral node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTArguments node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTArgumentList node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTAllocationExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTArrayDimensions node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTDefinedArrayDimension node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTUndefinedArrayDimension node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTArrayWithInit node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTExpressionStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTAssertStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTLabeledStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTBlock node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTVariableDeclarationStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTLocalVariableDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTEmptyStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTStatementExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTSwitchStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTSwitchCase node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTSwitchLabel node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTIfStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTWhileStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTDoStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTForStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTForEach node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTTernaryForCondition node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTStatementExpressionList node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTBreakStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTContinueStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTReturnStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTThrowStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTSynchronizedStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTTryStatement node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTResourcesSpecification node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTResource node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTCatchClauses node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTCatchClause node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTCatchParameter node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTCatchType node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTNormalAnnotation node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMarkerAnnotation node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTSingleMemberAnnotation node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMemberValuePairs node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMemberValuePair node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMemberValue node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTMemberValueArrayInitializer node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTAnnotationTypeDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTAnnotationTypeBody node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTAnnotationTypeMemberDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTAnnotationMethodDeclaration node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTDefaultValue node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTLambdaExpression node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTLambdaParameters node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTLambdaParameterList node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+
+    @Override
+    public R visit(final ASTLambdaBody node, final T data)
+    {
+        node.childrenAccept(this, data);
+        return null;
+    }
+}
+

parser/source/java/parser/org/adjective/syntactic/parser/PrintSourceVisitor.java

 
 public class PrintSourceVisitor implements JavaParserVisitor<Object, PrintStream>
 {
+    protected Object visitNode(Node node, PrintStream out)
+    {
+        return node.jjtAccept(this, out);
+    }
+
     private boolean printSource(PrintStream out, Node node)
     {
         if (node == null)
         {
             return false;
         }
-        node.jjtAccept(this, out);
+        visitNode(node, out);
         return true;
     }
 
     {
         for (ASTAnnotation annotation : annotations)
         {
-            annotation.jjtAccept(this, out);
+            visitNode(annotation, out);
             out.println();
         }
         return null;
     {
         printAnnotationSource(out, node);
         ModifierSet modifiers = node.getModifiers();
+        if (modifiers == null)
+        {
+            throw new IllegalArgumentException("Node: " + node + " has null modifiers");
+        }
         if (!modifiers.isEmpty())
         {
             out.print(modifiers);
             {
                 out.print(separator);
             }
-            node.jjtAccept(this, out);
+            visitNode(node, out);
         }
         return null;
     }
 
     private void printSpecial(final PrintStream out, final HasTokens node)
     {
-        for (Token special = node.jjtGetFirstToken().specialToken; special != null; special = special.next)
+        final Token token = node.jjtGetFirstToken();
+        if (token == null)
+        {
+            return;
+        }
+        for (Token special = token.specialToken; special != null; special = special.next)
         {
             out.println(special);
         }
         if (exceptions != null)
         {
             out.print(" throws ");
-            exceptions.jjtAccept(this, out);
+            visitNode(exceptions, out);
         }
         out.print(' ');
         return node.getBody().jjtAccept(this, out);
         node.getPrefix().jjtAccept(this, out);
         for (ExpressionSuffix suffix : node.getSuffixes())
         {
-            suffix.jjtAccept(this, out);
+            visitNode(suffix, out);
         }
         return null;
     }

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTAllocationExpression.java

 package org.adjective.syntactic.parser.ast;
 
 import org.adjective.syntactic.parser.BaseNode;
+import org.adjective.syntactic.parser.jj.JavaParserConstants;
+import org.adjective.syntactic.parser.jj.Token;
 import org.adjective.syntactic.parser.util.ArrayDimensionsAndInitialization;
 import org.adjective.syntactic.parser.util.ExpressionNode;
+import org.adjective.syntactic.parser.util.JavaType;
 import org.adjective.syntactic.parser.util.TypeNode;
 
 public class ASTAllocationExpression extends BaseNode implements ExpressionNode
         super(id);
     }
 
+    public ASTAllocationExpression(final JavaType type, final ASTArguments arguments, final ASTClassOrInterfaceBody body)
+    {
+        this(JavaParserTreeConstants.JJTALLOCATIONEXPRESSION);
+        final Token tokenNew = new Token();
+        tokenNew.image = "new";
+        tokenNew.kind= JavaParserConstants.NEW;
+        jjtSetFirstToken(tokenNew);
+        setChildren(super.makeTypeNode(type), arguments, body);
+    }
+
     public <R, T> R jjtAccept(JavaParserVisitor<R, T> visitor, T data)
     {
         return visitor.visit(this, data);

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTArguments.java

         super(id);
     }
 
+    public ASTArguments()
+    {
+        this(JavaParserTreeConstants.JJTARGUMENTS);
+    }
+
     public <R,T> R jjtAccept(JavaParserVisitor<R,T> visitor, T data)
     {
         return visitor.visit(this, data);

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTArraySuffix.java

-/* Generated By:JJTree: Do not edit this line. ASTArraySuffix.java Version 4.3 */
-/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=true,TRACK_TOKENS=true,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+/*
+ * ------------------------------------------------------------------------
+ *  Copyright 2013 Tim Vernum
+ *  ------------------------------------------------------------------------
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  ------------------------------------------------------------------------
+ */
+
 package org.adjective.syntactic.parser.ast;
 
-public
-class ASTArraySuffix extends org.adjective.syntactic.parser.BaseNode {
-  public ASTArraySuffix(int id) {
-    super(id);
-  }
+import org.adjective.syntactic.parser.BaseNode;
 
+public class ASTArraySuffix extends BaseNode
+{
+    public ASTArraySuffix(int id)
+    {
+        super(id);
+    }
 
-    /** Accept the visitor. **/
-  public <R,T> R jjtAccept(JavaParserVisitor<R,T> visitor, T data) {
-    return visitor.visit(this, data);
-  }
+    public ASTArraySuffix()
+    {
+        this(JavaParserTreeConstants.JJTARRAYSUFFIX);
+    }
+
+    public <R, T> R jjtAccept(JavaParserVisitor<R, T> visitor, T data)
+    {
+        return visitor.visit(this, data);
+    }
 }
-/* JavaCC - OriginalChecksum=55237e9c70395cc108e0b0250e2d9d98 (do not edit this line) */

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTArraySuffixList.java

         super(i);
     }
 
+    public ASTArraySuffixList()
+    {
+        this(JavaParserTreeConstants.JJTARRAYSUFFIXLIST);
+    }
+
     @Override
     public <R,T> R jjtAccept(JavaParserVisitor<R,T> visitor, T data)
     {

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTClassOrInterfaceBody.java

         super(id);
     }
 
-    public <R,T> R jjtAccept(JavaParserVisitor<R,T> visitor, T data)
+    public ASTClassOrInterfaceBody(final ASTClassOrInterfaceBodyElement... elements)
+    {
+        this(JavaParserTreeConstants.JJTCLASSORINTERFACEBODY);
+        setChildren(elements);
+    }
+
+    public <R, T> R jjtAccept(JavaParserVisitor<R, T> visitor, T data)
     {
         return visitor.visit(this, data);
     }

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTClassOrInterfaceBodyElement.java

         super(id);
     }
 
+    public ASTClassOrInterfaceBodyElement(final ASTMember member)
+    {
+        this(JavaParserTreeConstants.JJTCLASSORINTERFACEBODYELEMENT);
+        jjtAddChild(member, 0);
+    }
+
     public <R,T> R jjtAccept(JavaParserVisitor<R,T> visitor, T data)
     {
         return visitor.visit(this, data);

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTClassOrInterfaceType.java

 
 import org.adjective.syntactic.parser.BaseNode;
 import org.adjective.syntactic.parser.util.BaseType;
+import org.adjective.syntactic.parser.util.ParameterizedName;
 import org.adjective.syntactic.parser.util.TypeNode;
 
 import java.util.ArrayList;
         super(id);
     }
 
-    public <R,T> R jjtAccept(JavaParserVisitor<R,T> visitor, T data)
+    public ASTClassOrInterfaceType(final ASTParameterizedIdentifier[] nameComponents)
+    {
+        this(JavaParserTreeConstants.JJTCLASSORINTERFACETYPE);
+        setChildren(nameComponents);
+    }
+
+    public ASTClassOrInterfaceType(final ParameterizedName[] components)
+    {
+        this(JavaParserTreeConstants.JJTCLASSORINTERFACETYPE);
+        ASTParameterizedIdentifier[] children = new ASTParameterizedIdentifier[components.length];
+        for (int i = 0; i < components.length; i++)
+        {
+            if (components[i] instanceof ASTParameterizedIdentifier)
+            {
+                children[i] = (ASTParameterizedIdentifier) components[i];
+            }
+            else
+            {
+                children[i] = new ASTParameterizedIdentifier(components[i]);
+            }
+        }
+        setChildren(children);
+    }
+
+    public <R, T> R jjtAccept(JavaParserVisitor<R, T> visitor, T data)
     {
         return visitor.visit(this, data);
     }
         return getIdentifierName(identifiers);
     }
 
+    @Override
+    public ParameterizedName[] getParameterizedTypeName()
+    {
+        final ParameterizedName[] names = new ParameterizedName[jjtGetNumChildren()];
+        int i = 0;
+        for (ASTParameterizedIdentifier identifier : getComponents())
+        {
+            names[i++] = identifier;
+        }
+        return names;
+    }
+
     public Iterable<ASTParameterizedIdentifier> getComponents()
     {
         return allChildren(ASTParameterizedIdentifier.class);

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTExpression.java

         super(id);
     }
 
+    public ASTExpression(final ExpressionNode expression)
+    {
+        this(JavaParserTreeConstants.JJTEXPRESSION);
+        setChildren(expression);
+    }
+
     public <R,T> R jjtAccept(JavaParserVisitor<R,T> visitor, T data)
     {
         return visitor.visit(this, data);

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTFormalParameter.java

 package org.adjective.syntactic.parser.ast;
 
 import org.adjective.syntactic.parser.BaseNode;
-import org.adjective.syntactic.parser.util.*;
+import org.adjective.syntactic.parser.util.JavaType;
+import org.adjective.syntactic.parser.util.ModifierSet;
+import org.adjective.syntactic.parser.util.TypeNode;
+import org.adjective.syntactic.parser.util.VariableDeclarationNode;
 
-public class ASTFormalParameter extends BaseNode implements HasAnnotations, HasModifiers
+import java.util.Collections;
+import java.util.Map;
+
+public class ASTFormalParameter extends BaseNode implements VariableDeclarationNode
 {
     public ASTFormalParameter(int id)
     {
         super(id);
     }
 
-    public <R,T> R jjtAccept(JavaParserVisitor<R,T> visitor, T data)
+    public ASTFormalParameter(final JavaType type, boolean varargs, String name)
+    {
+        this(JavaParserTreeConstants.JJTFORMALPARAMETER);
+        setChildren(new ASTVariableModifiers(),
+                    makeTypeNode(type));
+        if (varargs)
+        {
+            appendChild(new ASTVarArgs());
+        }
+        appendChild(new ASTIdentifier(name));
+    }
+
+    public <R, T> R jjtAccept(JavaParserVisitor<R, T> visitor, T data)
     {
         return visitor.visit(this, data);
     }
     {
         return BaseNode.makeType(getTypeNode(), getArraySuffix());
     }
+
+    @Override
+    public boolean isMultiVariable()
+    {
+        return false;
+    }
+
+    @Override
+    public Map<String, VariableDeclarationNode> split()
+    {
+        return Collections.<String, VariableDeclarationNode>singletonMap(getName().getIdentifier(), this);
+    }
 }

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTFormalParameters.java

         super(id);
     }
 
+    public ASTFormalParameters(ASTFormalParameter... formalParameters)
+    {
+        this(JavaParserTreeConstants.JJTFORMALPARAMETERS);
+        setChildren(formalParameters);
+    }
+
     public <R,T> R jjtAccept(JavaParserVisitor<R,T> visitor, T data)
     {
         return visitor.visit(this, data);

parser/source/java/parser/org/adjective/syntactic/parser/ast/ASTIdentifier.java

 package org.adjective.syntactic.parser.ast;
 
+import org.adjective.syntactic.parser.jj.JavaParserConstants;
+
 public class ASTIdentifier extends org.adjective.syntactic.parser.BaseNode
 {
     public ASTIdentifier(int id)
         super(id);
     }
 
+    public ASTIdentifier(final String image)
+    {
+        this(JavaParserTreeConstants.JJTIDENTIFIER);
+        jjtSetFirstToken(makeToken(JavaParserConstants.IDENTIFIER, image));
+    }
+
     public <R, T> R jjtAccept(JavaParserVisitor<R, T> visitor, T data)
     {