/*
* JavaParserGenerator.java
*
* This work is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This work is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* As a special exception, the copyright holders of this library give
* you permission to link this library with independent modules to
* produce an executable, regardless of the license terms of these
* independent modules, and to copy and distribute the resulting
* executable under terms of your choice, provided that you also meet,
* for each linked independent module, the terms and conditions of the
* license of that module. An independent module is a module which is
* not derived from or based on this library. If you modify this
* library, you may extend this exception to your version of the
* library, but you are not obligated to do so. If you do not wish to
* do so, delete this exception statement from your version.
*
* Copyright (c) 2003 Per Cederberg. All rights reserved.
*/
package net.percederberg.grammatica.output;
import java.io.IOException;
import net.percederberg.grammatica.Grammar;
import net.percederberg.grammatica.code.CodeStyle;
import net.percederberg.grammatica.code.java.JavaFile;
import net.percederberg.grammatica.code.java.JavaPackage;
import net.percederberg.grammatica.parser.ProductionPattern;
import net.percederberg.grammatica.parser.TokenPattern;
/**
* A Java parser generator. This class generates the source code files
* needed for a Java parser.
*
* @author Per Cederberg, <per at percederberg dot net>
* @version 1.0
*/
public class JavaParserGenerator extends ParserGenerator {
/**
* The fully qualified Java package name.
*/
private String basePackage = null;
/**
* The Java class name prefix.
*/
private String baseName = null;
/**
* The public class and interface access flag.
*/
private boolean publicAccess = false;
/**
* The Java class comment.
*/
private String classComment = null;
/**
* Creates a new Java parser generator.
*
* @param grammar the grammar to use
*/
public JavaParserGenerator(Grammar grammar) {
super(grammar);
initialize();
}
/**
* Initializes various instance variables.
*/
private void initialize() {
StringBuffer buffer;
String str;
// Set base name
str = getGrammar().getFileName();
if (str.indexOf('/') >= 0) {
str = str.substring(str.lastIndexOf('/') + 1);
}
if (str.indexOf('\\') >= 0) {
str = str.substring(str.lastIndexOf('\\') + 1);
}
if (str.indexOf('.') > 0) {
str = str.substring(0, str.indexOf('.'));
}
if (Character.isLowerCase(str.charAt(0))) {
str = Character.toUpperCase(str.charAt(0)) + str.substring(1);
}
baseName = str;
// Create class comment
buffer = new StringBuffer();
str = getGrammar().getDeclaration(Grammar.AUTHOR_DECLARATION);
if (str != null) {
buffer.append("@author ");
buffer.append(str);
}
str = getGrammar().getDeclaration(Grammar.VERSION_DECLARATION);
if (str != null) {
if (buffer.length() > 0) {
buffer.append("\n");
}
buffer.append("@version ");
buffer.append(str);
}
classComment = buffer.toString();
}
/**
* Returns the Java package where the classes will be created.
*
* @return the fully qualified Java package name
*/
public String getBasePackage() {
return basePackage;
}
/**
* Sets the Java package name where the classes will be created.
*
* @param pkg the fully qualified package name
*/
public void setBasePackage(String pkg) {
this.basePackage = pkg;
}
/**
* Returns the Java class name prefix.
*
* @return the Java class name prefix
*/
public String getBaseName() {
return baseName;
}
/**
* Sets the Java class name prefix.
*
* @param name the Java class name prefix
*/
public void setBaseName(String name) {
this.baseName = name;
}
/**
* Returns the public access flag.
*
* @return true if the classes should have public access, or
* false otherwise
*/
public boolean getPublicAccess() {
return publicAccess;
}
/**
* Sets the public access flag.
*
* @param flag the new public access flag value
*/
public void setPublicAccess(boolean flag) {
publicAccess = flag;
}
/**
* Returns the Java code style to use.
*
* @return the Java code style to use
*/
public CodeStyle getCodeStyle() {
return CodeStyle.JAVA;
}
/**
* Returns the Java class comment.
*
* @return the Java class comment
*/
public String getClassComment() {
return classComment;
}
/**
* Writes the Java source code files.
*
* @throws IOException if the files couldn't be written correctly
*/
public void write() throws IOException {
Grammar grammar = getGrammar();
JavaConstantsFile constants = new JavaConstantsFile(this);
JavaTokenizerFile tokenizer = new JavaTokenizerFile(this);
JavaParserFile parser = new JavaParserFile(this, tokenizer);
JavaAnalyzerFile analyzer = new JavaAnalyzerFile(this);
TokenPattern token;
ProductionPattern production;
int i;
// Create token declarations
for (i = 0; i < grammar.getTokenPatternCount(); i++) {
token = grammar.getTokenPattern(i);
constants.addToken(token);
tokenizer.addToken(token, constants);
analyzer.addToken(token, constants);
}
// Create production constants
for (i = 0; i < grammar.getProductionPatternCount(); i++) {
production = grammar.getProductionPattern(i);
constants.addProduction(production);
parser.addProductionConstant(production);
analyzer.addProduction(production, constants);
}
// Create production definitions
for (i = 0; i < grammar.getProductionPatternCount(); i++) {
production = grammar.getProductionPattern(i);
parser.addProduction(production, constants);
}
// Write source code files
constants.writeCode();
tokenizer.writeCode();
parser.writeCode();
analyzer.writeCode();
}
/**
* Creates a Java file in the correct base directory. The package
* will be set if applicable.
*
* @return a new Java file
*/
public JavaFile createJavaFile() {
if (basePackage == null) {
return new JavaFile(getBaseDir());
} else {
return new JavaFile(getBaseDir(),
new JavaPackage(getBasePackage()));
}
}
}
|