org.codehaus.mojo.javacc.JTBJavaCCMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javacc-maven-plugin Show documentation
Show all versions of javacc-maven-plugin Show documentation
Maven 3 Plugin for processing JavaCC grammar files.
package org.codehaus.mojo.javacc;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.io.File;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.plexus.util.FileUtils;
/**
* Preprocesses ordinary grammar files (*.jtb
) with JTB and passes the output to JavaCC in order to
* finally generate a parser with parse tree actions.
Note: JTB requires Java 1.5 or higher. This goal will not work with earlier
* versions of the JRE.
*
* @goal jtb-javacc
* @phase generate-sources
* @since 2.4
* @author Benjamin Bentmann
* @version $Id: JTBJavaCCMojo.java 6282 2008-02-09 23:49:06Z bentmann $
*/
public class JTBJavaCCMojo
extends AbstractJavaCCMojo
{
/**
* This option is short for nodePackageName
= <packageName>.syntaxtree
and
* visitorPackageName
= <packageName>.visitor
. Note that this option takes
* precedence over nodePackageName
and visitorPackageName
if specified.
*
* @parameter expression="${package}"
*/
private String packageName;
/**
* This option specifies the package for the generated AST nodes. This value may use a leading asterisk to reference
* the package of the corresponding parser. For example, if the parser package is org.apache
and this
* parameter is set to *.demo
, the tree node classes will be located in the package
* org.apache.demo
. Default value is *.syntaxtree
.
*
* @parameter expression="${nodePackageName}"
*/
private String nodePackageName;
/**
* This option specifies the package for the generated visitors. This value may use a leading asterisk to reference
* the package of the corresponding parser. For example, if the parser package is org.apache
and this
* parameter is set to *.demo
, the visitor classes will be located in the package
* org.apache.demo
. Default value is *.visitor
.
*
* @parameter expression="${visitorPackageName}"
*/
private String visitorPackageName;
/**
* If true
, JTB will suppress its semantic error checking. Default value is false
.
*
* @parameter expression="${supressErrorChecking}"
*/
private Boolean supressErrorChecking;
/**
* If true
, all generated comments will be wrapped in <pre>
tags so that they
* are formatted correctly in API docs. Default value is false
.
*
* @parameter expression="${javadocFriendlyComments}"
*/
private Boolean javadocFriendlyComments;
/**
* Setting this option to true
causes JTB to generate field names that reflect the structure of the
* tree instead of generic names like f0
, f1
etc. Default value is false
.
*
* @parameter expression="${descriptiveFieldNames}"
*/
private Boolean descriptiveFieldNames;
/**
* The qualified name of a user-defined class from which all AST nodes will inherit. By default, AST nodes will
* inherit from the generated class Node
.
*
* @parameter expression="${nodeParentClass}"
*/
private String nodeParentClass;
/**
* If true
, all nodes will contain fields for its parent node. Default value is false
.
*
* @parameter expression="${parentPointers}"
*/
private Boolean parentPointers;
/**
* If true
, JTB will include JavaCC "special tokens" in the AST. Default value is false
.
*
* @parameter expression="${specialTokens}"
*/
private Boolean specialTokens;
/**
* If true
, JTB will generate the following files to support the Schema programming language:
*
* - Scheme records representing the grammar.
* - A Scheme tree building visitor.
*
* Default value is false
.
*
* @parameter expression="${scheme}"
*/
private Boolean scheme;
/**
* If true
, JTB will generate a syntax tree dumping visitor. Default value is false
.
*
* @parameter expression="${printer}"
*/
private Boolean printer;
/**
* The directory where the JavaCC grammar files (*.jtb
) are located. It will be recursively scanned
* for input files to pass to JTB. The parameters includes
and excludes
can be used to
* select a subset of files.
*
* @parameter expression="${sourceDirectory}" default-value="${basedir}/src/main/jtb"
*/
private File sourceDirectory;
/**
* The directory where the interim output from JTB will be stored. This directory will hold the prepared grammar
* files (*.jj
) along with their tree node and visitor files (*.java
). The
* prepared grammar files will then be passed on to JavaCC to generate the parser files.
*
* @parameter expression="${interimDirectory}" default-value="${project.build.directory}/generated-sources/jtb"
*/
private File interimDirectory;
/**
* The directory where the generated Java files will be stored. More precisely, the parser files generated by JavaCC
* together with some auxiliary files and the previously generated tree node and visitor files from JTB will be
* saved here. The directory will be registered as a compile source root of the project such that the generated
* files will participate in later build phases like compiling and packaging.
*
* @parameter expression="${outputDirectory}" default-value="${project.build.directory}/generated-sources/javacc"
*/
private File outputDirectory;
/**
* A set of Ant-like inclusion patterns used to select files from the source directory for processing. By default,
* the patterns **/*.jj
, **/*.JJ
, **/*.jtb
and
* **/*.JTB
are used to select grammar files.
*
* @parameter
*/
private String[] includes;
/**
* A set of Ant-like exclusion patterns used to prevent certain files from being processing. By default, this set if
* empty such that no files are excluded.
*
* @parameter
*/
private String[] excludes;
/**
* The granularity in milliseconds of the last modification date for testing whether a grammar file needs
* recompilation.
*
* @parameter expression="${lastModGranularityMs}" default-value="0"
*/
private int staleMillis;
/**
* {@inheritDoc}
*/
protected File getSourceDirectory()
{
return this.sourceDirectory;
}
/**
* {@inheritDoc}
*/
protected String[] getIncludes()
{
if ( this.includes != null )
{
return this.includes;
}
else
{
return new String[] { "**/*.jj", "**/*.JJ", "**/*.jtb", "**/*.JTB" };
}
}
/**
* {@inheritDoc}
*/
protected String[] getExcludes()
{
return this.excludes;
}
/**
* {@inheritDoc}
*/
protected File getOutputDirectory()
{
return this.outputDirectory;
}
/**
* {@inheritDoc}
*/
protected int getStaleMillis()
{
return this.staleMillis;
}
/**
* Gets the absolute path to the directory where the interim output from JTB will be stored.
*
* @return The absolute path to the directory where the interim output from JTB will be stored.
*/
private File getInterimDirectory()
{
return this.interimDirectory;
}
/**
* {@inheritDoc}
*/
protected void processGrammar( GrammarInfo grammarInfo )
throws MojoExecutionException, MojoFailureException
{
File jtbFile = grammarInfo.getGrammarFile();
File jtbDirectory = jtbFile.getParentFile();
// determine target directory of grammar file (*.jj) generated by JTB
File jjDirectory = new File( getInterimDirectory(), grammarInfo.getParserDirectory() );
// determine output directory of tree node files (*.java) generated by JJTree
String nodePackage = grammarInfo.resolvePackageName( getNodePackageName() );
File nodeDirectory = new File( getInterimDirectory(), nodePackage.replace( '.', File.separatorChar ) );
// determine output directory of visitor files (*.java) generated by JJTree
String visitorPackage = grammarInfo.resolvePackageName( getVisitorPackageName() );
File visitorDirectory = new File( getInterimDirectory(), visitorPackage.replace( '.', File.separatorChar ) );
// determine output directory of parser file (*.java) generated by JavaCC
File parserDirectory = new File( getOutputDirectory(), grammarInfo.getParserDirectory() );
// generate final grammar file and the node/visitor files
JTB jtb = newJTB();
jtb.setInputFile( jtbFile );
jtb.setOutputDirectory( jjDirectory );
jtb.setNodeDirectory( nodeDirectory );
jtb.setVisitorDirectory( visitorDirectory );
jtb.setNodePackageName( nodePackage );
jtb.setVisitorPackageName( visitorPackage );
jtb.run();
// copy generated tree node files to output directory
File nodeDir = new File( getOutputDirectory(), nodePackage.replace( '.', File.separatorChar ) );
try
{
getLog().debug( "Copying tree nodes files: " + nodeDirectory + " -> " + nodeDir );
FileUtils.copyDirectory( nodeDirectory, nodeDir, "*.java", "" );
}
catch ( Exception e )
{
throw new MojoExecutionException( "Failed to copy tree nodes files to output directory: " + nodeDirectory
+ " -> " + nodeDir, e );
}
// copy generated visitor files to output directory
File visitorDir = new File( getOutputDirectory(), visitorPackage.replace( '.', File.separatorChar ) );
try
{
getLog().debug( "Copying visitor files: " + visitorDirectory + " -> " + visitorDir );
FileUtils.copyDirectory( visitorDirectory, visitorDir, "*.java", "" );
}
catch ( Exception e )
{
throw new MojoExecutionException( "Failed to copy visitor files to output directory: " + visitorDirectory
+ " -> " + visitorDir, e );
}
// copy custom source files to output directory
try
{
getLog().debug( "Copying custom source files: " + jtbDirectory + " -> " + parserDirectory );
FileUtils.copyDirectory( jtbDirectory, parserDirectory, "*.java", "" );
}
catch ( Exception e )
{
throw new MojoExecutionException( "Failed to copy custom source files to output directory:" + jtbDirectory
+ " -> " + parserDirectory, e );
}
// generate parser file
JavaCC javacc = newJavaCC();
javacc.setInputFile( jtb.getOutputFile() );
javacc.setOutputDirectory( parserDirectory );
javacc.run();
}
/**
* Gets the effective package name for the AST node files.
*
* @return The effective package name for the AST node files, never null
.
*/
private String getNodePackageName()
{
if ( this.packageName != null )
{
return this.packageName + ".syntaxtree";
}
else if ( this.nodePackageName != null )
{
return this.nodePackageName;
}
else
{
return "*.syntaxtree";
}
}
/**
* Gets the effective package name for the visitor files.
*
* @return The effective package name for the visitor files, never null
.
*/
private String getVisitorPackageName()
{
if ( this.packageName != null )
{
return this.packageName + ".visitor";
}
else if ( this.visitorPackageName != null )
{
return this.visitorPackageName;
}
else
{
return "*.visitor";
}
}
/**
* Creates a new facade to invoke JTB. Most options for the invocation are derived from the current values of the
* corresponding mojo parameters. The caller is responsible to set the input file, output directories and packages
* on the returned facade.
*
* @return The facade for the tool invocation, never null
.
*/
private JTB newJTB()
{
JTB jtb = new JTB();
jtb.setLog( getLog() );
jtb.setDescriptiveFieldNames( this.descriptiveFieldNames );
jtb.setJavadocFriendlyComments( this.javadocFriendlyComments );
jtb.setNodeParentClass( this.nodeParentClass );
jtb.setParentPointers( this.parentPointers );
jtb.setPrinter( this.printer );
jtb.setScheme( this.scheme );
jtb.setSpecialTokens( this.specialTokens );
jtb.setSupressErrorChecking( this.supressErrorChecking );
return jtb;
}
}