import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.*;
import java.util.logging.Level;
import java.io.*;
import java.util.*;
import java.lang.*;
//-----------------------------------------------------------------------//
// Main class:
//-----------------------------------------------------------------------//
/**
* Provides a <code>driver</code> to translate a Bali source file into a set of
* Jak source files.
*/
public class Main {
final public static String resourcePrefix = "resource/" ;
/**
* Handles argument parsing, data collecting, and code generation
*/
public Object driver( String[] args ) throws Throwable {
Arguments argsData = null;
try {
argsData = parseArguments( Arrays.asList( args ) ) ;
}
catch ( IllegalArgumentException exception ) {
System.err.println(exception.getMessage());
usage () ;
System.exit (1) ;
}
argsData.collectClass();
generateObject(argsData);
return null;
}
/**
* Generates Jak files and, optionally, a Main class.
*/
public void generateObject(Arguments argsData) {
genJakFile(argsData);
genMain(argsData);
}
/**
* Processes a {@link List} of {@link String} arguments that specify
* the input file and options.
*
* @see #usage()
*/
private Arguments parseArguments( List args ) throws IOException {
Arguments argsData = new Arguments () ;
for ( Iterator p = args.iterator() ; p.hasNext() ; ) {
String arg = ( String ) p.next();
if (arg.charAt (0) != '-')
throw new IllegalArgumentException (
"unrecognized argument: "
+ arg
);
// Options without a value parameter go here:
//
if( arg.equals( "-f" ) ) {
argsData.setOutputMain(true);
argsData.setFileInput(true);
continue;
}
//output Main with std input
if( arg.equals( "-s" ) ) {
argsData.setOutputMain(true);
argsData.setStdInput(true);
continue;
}
// Options that require a single value parameter go here:
//
if (! p.hasNext ())
throw new IllegalArgumentException (
"no value specified for option: "
+ arg
) ;
//get classname file
if( arg.equals( "-l" ) ) {
argsData.setClassFile( (String) p.next () );
continue;
}
//get grammar file
if( arg.equals( "-b" ) ) {
argsData.setBaliFile( (String) p.next () );
continue;
}
//parse all methods
if( arg.equals( "-m" ) ) {
String[] methods = ((String) p.next ()) . split (";") ;
for( int i = 0; i < methods.length; i++ )
argsData.addMethod(methods[i]);
continue;
}
//get layer name
if( arg.equals( "-layer" ) ) {
argsData.setLayer( (String) p.next () );
continue;
}
//get start name
if( arg.equals( "-start" ) ) {
argsData.setStart( (String) p.next () );
continue;
}
throw new IllegalArgumentException (
"unrecognized option: "
+ arg
) ;
}
return argsData ;
}
protected static void usage() {
System.err.println( "Usage: bali2layer.Main [-f] [-s]" +
"[-m \"<Method> [;<method>]\"] [-l classFile]" +
"[-b grammar file] -start sname -layer lname");
System.err.println( " -f output main class with file input" );
System.err.println( " -s output main class with std input" );
System.err.println( " -m specify methods");
System.err.println( " -l file of a list of classes" );
System.err.println( " -b bali grammer file" );
System.err.println( " sname name of start production" );
System.err.println( " lname name of layer file" );
System.err.println( " ClassFile file containing class names to generate" );
}
/**
* Generates Jak files
*/
private static void genJakFile(Arguments args) {
for(Iterator p = args.getClasses().iterator(); p.hasNext(); ) {
String className = (String) p.next();
templateClass(args, className) ;
}
}
/**
* Generates a Main class
*/
private static void genMain(Arguments args) {
try{
if (args.doesOutputMain()) {
PrintWriter outfile = new PrintWriter( new BufferedWriter(
new FileWriter("Main.jak"))) ;
outfile.println("layer " + args.getLayer() + ";");
copyResource( outfile, resourcePrefix + "JakFileHeader.txt" );
if ( args.doesFileInput()) {
copyResource( outfile, resourcePrefix + "FileInputTemplateHeader.txt" );
outfile.println( " "+args.getStart()+" inputRoot = null;" );
outfile.println( " try {" );
outfile.println( " inputRoot = ("+args.getStart()+") myParser.parseAll() ;" );
copyResource( outfile, resourcePrefix + "FileInputTemplateFooter.txt" );
}
else {
copyResource( outfile, resourcePrefix + "StdInputTemplateHeader.txt" );
outfile.println();
outfile.println( " (("+args.getStart()+") root).print();" );
outfile.println( " System.out.println();" );
outfile.println( " (("+args.getStart()+") root).execute();" );
outfile.println( " pw.flush();" );
outfile.println( "" );
outfile.println( " // Step 5.5: now dump the parse tree" );
outfile.println( " // this code can be removed for production systems" );
outfile.println( "" );
outfile.println( " System.out.println(\"Dump root\");" );
outfile.println( " root.PrettyDump();" );
outfile.println( "" );
outfile.println( " } while (true); // end Language statement loop" );
outfile.println( " } //end main()" );
outfile.println( " } // end Main class" );
}
outfile.close() ;
}
}
catch (IOException e) {
System.err.println( e.getMessage() );
}
}
/**
* Copies a template to a file
*/
private static void copyResource( PrintWriter outfile, String resource ) {
InputStream inp = null ;
try {
inp = Main.class.getResourceAsStream(resource) ;
BufferedReader reader = new BufferedReader (
new InputStreamReader(inp, "ISO-8859-1")
) ;
String line;
while ((line = reader.readLine()) != null)
outfile.println (line) ;
inp.close();
} catch ( IOException e ) {
System.err.println( e.getMessage() );
}
}
/**
* Generates Jak files
*
*/
private static void templateClass( Arguments args, String className) {
ClassBuilder klass = new ClassBuilder () ;
klass.addModifier (Modifier.REFINES) ;
klass.setClassName (className) ;
for (Iterator p = args.getMethods().iterator () ; p.hasNext () ; )
klass.addMethod ( (MethodBuilder) p.next () ) ;
PrintWriter PWriter = null ;
try {
PWriter =new PrintWriter( new BufferedWriter(
new FileWriter (className + ".jak"))) ;
PWriter.println("layer " + args.getLayer() + ";");
copyResource(PWriter, resourcePrefix + "JakFileHeader.txt" );
PWriter.println (klass.toString ()) ;
PWriter.close();
}
catch (IOException exception) {
System.err.println (exception.getMessage ()) ;
System.exit (1) ;
}
}
}