org.codehaus.mojo.javacc.GrammarInfo 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 java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.codehaus.plexus.util.FileUtils;
/**
* This bean holds some output related information about a JavaCC grammar file. It assists in determining the exact
* output location for the generated parser file.
*
* @author Benjamin Bentmann
* @version $Id: GrammarInfo.java 7008 2008-05-18 10:29:21Z bentmann $
*/
class GrammarInfo
{
/**
* The absolute path to the base directory in which the grammar file resides.
*/
private final File sourceDirectory;
/**
* The path to the grammar file (relative to its source directory, e.g. "grammars/MyParser.jj").
*/
private final String grammarFile;
/**
* The declared package for the generated parser (e.g. "org.apache").
*/
private final String parserPackage;
/**
* The path to the directory of the parser package (relative to a source root directory, e.g. "org/apache").
*/
private final String parserDirectory;
/**
* The simple name of the generated parser (e.g. "MyParser").
*/
private final String parserName;
/**
* The path to the generated parser file (relative to a source root directory, e.g. "org/apache/MyParser.java").
*/
private final String parserFile;
/**
* Creates a new info from the specified grammar file.
*
* @param sourceDir The absolute path to the base directory in which the grammar file resides, must not be
* null
.
* @param inputFile The path to the grammar file (relative to the source directory), must not be null
.
* @throws IOException If reading the grammar file failed.
*/
public GrammarInfo( File sourceDir, String inputFile )
throws IOException
{
this( sourceDir, inputFile, null );
}
/**
* Creates a new info from the specified grammar file.
*
* @param sourceDir The absolute path to the base directory in which the grammar file resides, must not be
* null
.
* @param inputFile The path to the grammar file (relative to the source directory), must not be null
.
* @param packageName The package name for the generated parser, may be null
to use the package
* declaration from the grammar file.
* @throws IOException If reading the grammar file failed.
*/
public GrammarInfo( File sourceDir, String inputFile, String packageName )
throws IOException
{
if ( !sourceDir.isAbsolute() )
{
throw new IllegalArgumentException( "source directory is not absolute: " + sourceDir );
}
this.sourceDirectory = sourceDir;
File inFile = new File( inputFile );
if ( !inFile.isAbsolute() )
{
this.grammarFile = inFile.getPath();
}
else if ( inFile.getPath().startsWith( sourceDir.getPath() ) )
{
this.grammarFile = inFile.getPath().substring( sourceDir.getPath().length() + 1 );
}
else
{
throw new IllegalArgumentException( "input file is not relative to source directory:" + inputFile );
}
// NOTE: JavaCC uses the platform default encoding to read files, so must we
String grammar = FileUtils.fileRead( getGrammarFile() );
// TODO: Once the parameter "packageName" from the javacc mojo has been deleted, remove our parameter, too.
if ( packageName == null )
{
this.parserPackage = findPackageName( grammar );
}
else
{
this.parserPackage = packageName;
}
this.parserDirectory = this.parserPackage.replace( '.', File.separatorChar );
String name = findParserName( grammar );
if ( name.length() <= 0 )
{
this.parserName = FileUtils.removeExtension( inFile.getName() );
}
else
{
this.parserName = name;
}
if ( this.parserDirectory.length() > 0 )
{
this.parserFile = new File( this.parserDirectory, this.parserName + ".java" ).getPath();
}
else
{
this.parserFile = this.parserName + ".java";
}
}
/**
* Extracts the declared package name from the specified grammar file.
*
* @param grammar The contents of the grammar file, must not be null
.
* @return The declared package name or an empty string if not found.
*/
private String findPackageName( String grammar )
{
final String packageDeclaration = "package\\s+([^\\s.;]+(\\.[^\\s.;]+)*)\\s*;";
Matcher matcher = Pattern.compile( packageDeclaration ).matcher( grammar );
if ( matcher.find() )
{
return matcher.group( 1 );
}
return "";
}
/**
* Extracts the simple parser name from the specified grammar file.
*
* @param grammar The contents of the grammar file, must not be null
.
* @return The parser name or an empty string if not found.
*/
private String findParserName( String grammar )
{
final String parserBegin = "PARSER_BEGIN\\s*\\(\\s*([^\\s\\)]+)\\s*\\)";
Matcher matcher = Pattern.compile( parserBegin ).matcher( grammar );
if ( matcher.find() )
{
return matcher.group( 1 );
}
return "";
}
/**
* Gets the absolute path to the grammar file.
*
* @return The absolute path to the grammar file, never null
.
*/
public File getGrammarFile()
{
return new File( this.sourceDirectory, this.grammarFile );
}
/**
* Gets the path to the grammar file (relative to its source directory).
*
* @return The path to the grammar file (relative to its source directory), never null
.
*/
public String getRelativeGrammarFile()
{
return this.grammarFile;
}
/**
* Resolves the specified package name against the package name of the parser generated from this grammar. To
* reference the parser package, the input string may use the prefix "*". For example, if the package for the parser
* is "org.apache" and the input string is "*.node", the resolved package is "org.apache.node". The period after the
* asterisk is significant, i.e. in the previous example the input string "*node" would resolve to "org.apachenode".
*
* @param packageName The package name to resolve, may be null
.
* @return The resolved package name or null
if the input string was null
.
*/
public String resolvePackageName( String packageName )
{
String resolvedPackageName = packageName;
if ( resolvedPackageName != null && resolvedPackageName.startsWith( "*" ) )
{
resolvedPackageName = getParserPackage() + resolvedPackageName.substring( 1 );
if ( resolvedPackageName.startsWith( "." ) )
{
resolvedPackageName = resolvedPackageName.substring( 1 );
}
}
return resolvedPackageName;
}
/**
* Gets the declared package for the generated parser (e.g. "org.apache").
*
* @return The declared package for the generated parser (e.g. "org.apache") or an empty string if no package
* declaration was found, never null
.
*/
public String getParserPackage()
{
return this.parserPackage;
}
/**
* Gets the path to the directory of the parser package (relative to a source root directory, e.g. "org/apache").
*
* @return The path to the directory of the parser package (relative to a source root directory, e.g. "org/apache")
* or an empty string if no package declaration was found, never null
.
*/
public String getParserDirectory()
{
return this.parserDirectory;
}
/**
* Gets the simple name of the generated parser (e.g. "MyParser")
*
* @return The simple name of the generated parser (e.g. "MyParser"), never null
.
*/
public String getParserName()
{
return this.parserName;
}
/**
* Gets the path to the parser file (relative to a source root directory, e.g. "org/apache/MyParser.java").
*
* @return The path to the parser file (relative to a source root directory, e.g. "org/apache/MyParser.java"), never
* null
.
*/
public String getParserFile()
{
return this.parserFile;
}
/**
* Gets a string representation of this bean. This value is for debugging purposes only.
*
* @return A string representation of this bean.
*/
public String toString()
{
return getGrammarFile() + " -> " + getParserFile();
}
}