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