import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import java.lang.String;
public class Arguments {
public void setOutputMain(boolean t) {
outputMain = t;
}
public void setFileInput(boolean t) {
fileInput = t;
}
public void setStdInput(boolean t) {
stdInput = t;
}
public void setStart (String s) {
Start = s;
}
public void setClassFile (String s) {
classFile = s;
}
public void setLayer (String s) {
Layer = s;
}
public void setBaliFile (String s) {
baliFile = s;
}
public void print() {
//print out all collected classes
for(Iterator p = classes.iterator(); p.hasNext(); ) {
String name = (String) p.next() ;
System.out.println(name);
}
System.out.println();
System.out.println("outputMain = " + outputMain);
System.out.println("fileInput = " + fileInput);
System.out.println("stdInput = " + stdInput);
System.out.println("Start = " + Start);
System.out.println("Layer = " + Layer);
System.out.println("classFile = " + classFile);
System.out.println("baliFile = " + baliFile);
System.out.println();
}
/**
* Given a method signature return the reference form, parameter type,
* return type.
*/
public void addMethod (String s) {
MethodBuilder method = new MethodBuilder () ;
String[] m = decompose(s, method);
String returnType = m[0].trim();
String name = m[1];
String type = m[2];
String parm = m[3];
method.addModifier(Modifier.PUBLIC);
method.setReturn (name, returnType) ;
method.endLine();
if(!returnType.equals("void"))
method.append("return ");
method.append ("Super(" + type + ")." + name + "(" + parm + ");");
Methods.add (method) ;
}
/**
* Given a method signature and optional method object, return string array with:
* [0] method type,
* [1] method name,
* [2] formal parameter list,
* [3] parameter call list
* if method object present, parameters are added
*/
public String[] decompose(String s, MethodBuilder method ) {
String[] result = new String[4];
Matcher methodMatcher = methodPattern.matcher (s) ;
if (! methodMatcher.matches ())
throw new IllegalArgumentException (
"invalid method signature: "
+ s
) ;
result[1] = methodMatcher.group (2);
result[0] = methodMatcher.group (1);
if(result[0]== null) result[0]="void";
String arg = methodMatcher.group (3);
String type = "";
String parm = "";
if(arg.length() > 0) {
Matcher argMatcher = argPattern.matcher (arg) ;
while (argMatcher.find ()) {
String t = argMatcher.group (1) ;
String p = argMatcher.group (2) ;
type += t + ",";
parm += p + ",";
if (method!=null)
method.addParameter (p, t) ;
}
type = type.substring(0, type.length()-1);
parm = parm.substring(0, parm.length()-1);
}
result[2] = type;
result[3] = parm;
return result;
}
/**
* Collects class names from a class list file or a bali
* grammar file
*/
public void collectClass() throws Throwable {
StringBuffer className = new StringBuffer();
if(classFile != null) {
readFile(className,classFile);
}else if (baliFile != null) {
File argSourceFile = parseSourceFile( baliFile );
Collector collector = collectSource( argSourceFile ) ;
collector.collectClasses( className );
if( !grammarRefinement( baliFile ) ) {
Start = collector.baliRules.getStartName();
}
}
String s = className.toString();
StringTokenizer st = new StringTokenizer(s);
while ( st.hasMoreTokens() ) {
classes.add(st.nextToken());
}
}
/**
* Read in class list file
*/
private void readFile( StringBuffer buffer, String fileName ) {
try {
FileReader fr = new FileReader( fileName ) ;
BufferedReader reader = new BufferedReader( fr ) ;
char[] readBuffer = new char[1024] ;
int count = reader.read( readBuffer, 0, readBuffer.length ) ;
while ( count > -1 ) {
if ( count > 0 )
buffer.append( readBuffer, 0, count ) ;
count = reader.read( readBuffer, 0, readBuffer.length ) ;
}
fr.close();
}
catch ( IOException e ) {
System.err.println( e.getMessage() );
}
}
/**
* Checks if a Bali file is a base grammar or a grammar extension
* @return true if it's an extension
*
*/
private boolean grammarRefinement( String fileName ) {
String line;
try {
BufferedReader infile = new BufferedReader( new FileReader( fileName ) );
while( ( line = infile.readLine() ) != null ) {
line = line.trim();
if( line.startsWith( "/*" ) ) {
while( !line.endsWith( "*/" ) && line != null )
line = infile.readLine();
line = infile.readLine();
line = line.trim();
}
if( line.startsWith( "require" ) )
return true;
}
}
catch ( IOException e ) {
System.err.println( e.getMessage() );
}
return false;
}
private File parseSourceFile( String fileName ) {
File file = new File( fileName ) ;
if ( ! file.exists() )
throw new IllegalArgumentException( "file doesn't exist: "
+ fileName ) ;
if ( ! file.canRead() )
throw new IllegalArgumentException( "file can't be read: "
+ fileName ) ;
return file ;
}
/**
* Processes an input {@link File} (with Bali source code) into a parse
* tree, then running a {@link Collector} over the tree to gather
* all necessary data for later code generation.
*
* @return {@link Collector} with collected data from parse tree.
*
*/
private Collector collectSource( File inpFile )
throws IOException, ParseException {
Reader reader = new BufferedReader( new InputStreamReader( new FileInputStream( inpFile ),
"ISO-8859-1" ) ) ;
Parser parser = Parser.getInstance( reader ) ;
BaliParse tree = ( BaliParse ) parser.parseAll () ;
reader.close() ;
Collector collector = new Collector() ;
collector.dispatch( tree ) ;
return collector ;
}
public List getClasses() {
return classes;
}
public boolean doesOutputMain() {
return outputMain;
}
public boolean doesFileInput() {
return fileInput;
}
public boolean doesStdInput () {
return stdInput;
}
public String getStart() {
return Start;
}
public String getLayer() {
return Layer;
}
public String getClassFile() {
return classFile;
}
public String getBaliFile() {
return baliFile;
}
public List getMethods() {
return Methods;
}
private List classes = new ArrayList();
private boolean outputMain = false; //output a Main class
private boolean fileInput = false; //Main takes a file as input
private boolean stdInput = false; //Main gets input from stdin
private String Start = null ;
private String Layer = null ;
private String classFile = null ;
private String baliFile = null ;
private List Methods = new ArrayList();
final private static Pattern argPattern ;
final private static Pattern methodPattern ;
static {
String nameRex = "[$_a-zA-Z][$_a-zA-Z0-9]*" ;
String typeRex = nameRex + "(?:[.]" + nameRex + ")*" ;
String argRex = typeRex + "\\s+" + nameRex ;
String argsRex = "(?:" + argRex + "(?:\\s*[,]\\s*" + argRex + ")*)?" ;
argPattern = Pattern.compile (
"\\s*"
+ "(" + typeRex + ")"
+ "\\s*"
+ "(" + nameRex + ")"
+ "\\s*(?:[,])?\\s*"
) ;
methodPattern = Pattern.compile (
"\\s*"
+ "(" + typeRex + "\\s+)?"
+ "\\s*"
+ "(" + nameRex + ")"
+ "\\s*[(]\\s*"
+ "(" + argsRex + ")"
+ "\\s*[)]\\s*"
) ;
}
}