/* Copyright (c) 2006, Sun Microsystems, Inc.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Sun Microsystems, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

This directory contains an example of using the Visitor design pattern
with JJTree.  Like the Transformer example, it shows how a Java
program can be processed into a slightly different form.

In this case the input code is transformed so that each class has a
jjtAccept() method inserted.  This might be useful for updating node
files created with an earlier version of JJTree so that they can be
used with the Visitor support.

Here is an overview of the source files:

Java1.1.jjt

  This JJTree source file has been slightly modified from the Java 1.1
  grammar distributed in the JavaGrammars examples directory.  Here
  are the main differences:

  1) Removed the main method from the parser class;

  2) Added a couple of JJTree options;

  3) Made the CompilationUnit production return a root AST node;

  4) Made white space SPECIAL_TOKENs rather than SKIPs;

  These changes illustrate how a JavaCC grammar can be used with
  JJTree with very little modification.  In particular, there are no
  node annotations -- instead each production in the grammar is
  represented as a node.

Main.java

  Simply calls the parser to create the AST, creates a Visitor, and
  then asks the root node to accept the visitor.

SimpleNode.java

  This is modified from the automatically generated file.  SimpleNodes
  now maintain their first and last tokens so that the input can be
  reconstituted.  The jjtOpen() and jjtClose() methods are used as
  hooks to collect and store these tokens.  The NODE_USES_PARSER
  option is specified so that the parser object is available to these
  methods.

UnparseVisitor.java

  This is a generally useful Visitor that simply unparses the nodes
  that it visits.  It is intended to be a superclass for
  transformation-specific Visitors such as AddAcceptVisitor.

AddAcceptVisitor.java

  This is a Visitor for a particular transformation.  It extends
  UnparseVisitor and overrides methods for those nodes that require
  special treatment.  In this case, only the visit method for
  ClassBodyDeclaration nodes needs to be overridden.

  The visitor determines whether the node currently being visited is
  the first child of its parent, and if so it inserts the new text.
  It makes an attempt to indent the new text at the same level as the
  current node.


Here's how to build the transformer:

1) Run the JJTree on the grammar.  It will generate many node files
because the MULTI option is set.

trane% jjtree Java1.1.jjt 
Java Compiler Compiler Version 2.0 (Tree Builder)
Copyright (c) 1996-1999 Sun Microsystems, Inc.
Copyright (c) 1997-1999 Metamata, Inc.
(type "jjtree" with no arguments for help)
Reading from file Java1.1.jjt . . .
File "Node.java" does not exist.  Will create one.
File "ASTCompilationUnit.java" does not exist.  Will create one.
File "ASTPackageDeclaration.java" does not exist.  Will create one.
  ... lots more nodes generated here
File "ASTSynchronizedStatement.java" does not exist.  Will create one.
File "ASTTryStatement.java" does not exist.  Will create one.
Annotated grammar generated successfully in Java1.1.jj
trane% 

2) Run JavaCC on the generated grammar.

trane% javacc Java1.1.jj
Java Compiler Compiler Version 2.0 (Parser Generator)
Copyright (c) 1996-1999 Sun Microsystems, Inc.
Copyright (c) 1997-1999 Metamata, Inc.
(type "javacc" with no arguments for help)
Reading from file Java1.1.jj . . .
File "TokenMgrError.java" does not exist.  Will create one.
File "ParseException.java" does not exist.  Will create one.
File "Token.java" does not exist.  Will create one.
File "ASCII_UCodeESC_CharStream.java" does not exist.  Will create one.
Parser generated successfully.
trane% 

3) Ensure that your class path is set up correctly.  The examples
directory (above VTransformer) should be in your class path.

4) Compile the Java files

trane% javac Main.java

5) And finally run it.  It works as a filter now, but it would be
straightforward to make it take file names as arguments.  The
example below shows how to apply the filter on Main.java itself.

trane% java Main < Main.java > Main.new
Reading from standard input...
Thank you.
trane%
