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) ; } } }