1 package fri.patterns.interpreter.parsergenerator.util; 2 3 import java.io.*; 4 import java.util.*; 5 import fri.patterns.interpreter.parsergenerator.Token; 6 import fri.patterns.interpreter.parsergenerator.parsertables.*; 7 import fri.patterns.interpreter.parsergenerator.syntax.*; 8 import fri.patterns.interpreter.parsergenerator.syntax.builder.SyntaxBuilder; 9 10 26 27 public abstract class SourceGenerator 28 { 29 35 public static void generateSemanticSkeleton(Syntax syntax, String className, String pkgName) 36 throws Exception 37 { 38 String fileName = className+"Semantic.java"; 39 40 String dirName = pkgName != null && pkgName.length() > 0 41 ? pkgName.replace('.', File.separatorChar) 42 : System.getProperty("user.dir"); 43 44 File out = new File(dirName, fileName); 45 46 if (out.exists()) { 47 throw new IllegalStateException ("Will not overwrite "+out.getAbsolutePath()+". Please check the file for implementation and remove it!"); 48 } 49 else { 50 new File(dirName).mkdirs(); FileWriter fw = new FileWriter(out); 52 new SemanticSkeletonGenerator(syntax, className, pkgName, fw); 53 System.err.println("Wrote semantic skeleton to file: "+out); 54 } 55 } 56 57 58 64 public static void generateParserTable(AbstractParserTables parserTables, String className, String pkgName) 65 throws Exception 66 { 67 String fullName = (pkgName != null ? pkgName+"." : "")+className; 68 parserTables.toSourceFile(fullName); 69 } 70 71 72 78 public static void generateSyntaxImpl( 79 Syntax syntax, 80 String className, 81 String pkgName, 82 List initialNonterminals) 83 throws IOException 84 { 85 String origClsName = className; 86 className = className+"Syntax"; 87 String fileName = (pkgName != null ? pkgName+"."+className : className); 88 fileName = fileName.replace('.', File.separatorChar)+".java"; 89 Writer f = new BufferedWriter(new FileWriter(fileName)); 90 91 if (pkgName != null) 92 fwrite("package "+pkgName+";\n\n", f); 93 94 fwrite("/**\n", f); 95 fwrite(" * DO NOT EDIT - Syntax generated from "+origClsName+".syntax\n", f); 96 fwrite(" * at "+new Date()+"\n", f); 97 fwrite(" * by fri.patterns.interpreter.parsergenerator.util.SourceGenerator.\n", f); 98 fwrite(" */\n\n", f); 99 100 fwrite("import fri.patterns.interpreter.parsergenerator.syntax.*;\n\n", f); 101 fwrite("public final class "+className+" extends Syntax\n", f); fwrite("{\n", f); 103 104 for (int i = 0; i < initialNonterminals.size(); i++) fwrite(" public static final String "+initialNonterminals.get(i)+" = \""+initialNonterminals.get(i)+"\";\n", f); 106 fwrite("\n", f); 107 108 fwrite(" public "+className+"() {\n", f); fwrite(" super("+syntax.size()+");\n\n", f); 110 fwrite(" Rule rule;\n", f); 111 112 for (int i = 0; i < syntax.size(); i++) { 113 Rule rule = syntax.getRule(i); 114 String nt = rule.getNonterminal(); 115 if (initialNonterminals.indexOf(nt) < 0) nt = "\""+nt+"\""; 117 fwrite("\n rule = new Rule("+nt+", "+rule.rightSize()+"); // "+i+"\n", f); 118 119 for (int j = 0; j < rule.rightSize(); j++) { 120 String rightSymbol = rule.getRightSymbol(j); 121 if (Token.isTerminal(rightSymbol)) 122 fwrite(" rule.addRightSymbol(\""+SyntaxUtil.maskQuoteAndBackslash(rightSymbol)+"\");\n", f); 123 else 124 if (initialNonterminals.indexOf(rightSymbol) >= 0) fwrite(" rule.addRightSymbol("+rightSymbol+");\n", f); 126 else 127 fwrite(" rule.addRightSymbol(\""+rightSymbol+"\");\n", f); 128 } 129 fwrite(" addRule(rule);\n", f); 130 } 131 fwrite(" }\n", f); 132 fwrite("}\n", f); 133 134 f.close(); 135 System.err.println("Generated Syntax source file: "+fileName); 136 } 137 138 private static void fwrite(String line, Writer f) 139 throws IOException 140 { 141 f.write(line, 0, line.length()); 142 } 143 144 145 146 private SourceGenerator() {} 148 149 150 151 public static void main(String [] args) { 152 if (args.length <= 0 || args[0].startsWith("-h")) { 153 System.err.println("SYNTAX: java "+SourceGenerator.class.getName()+" [semantic|LALR|SLR|LR] file.syntax [file.syntax ...]"); 154 System.err.println(" LALR|SLR|LR: Generates ParserTable implementation(s) of passed grammar file(s)."); 155 System.err.println(" else: Generates syntax implementation(s) of passed grammar file(s)."); 156 System.err.println(" CAUTION: Files MUST have relative pathes!"); 157 System.exit(1); 158 } 159 else { 160 String type = args[0].equals("SLR") || args[0].equals("LR") || args[0].equals("LALR") ? args[0] : null; 161 boolean semantic = args[0].equals("semantic"); 162 int i = (type != null || semantic) ? 1 : 0; 163 164 for (; i < args.length; i++) { 165 File f = new File(args[i]); 166 167 if (f.exists() == false || f.isFile() == false || f.canRead() == false) { 168 System.err.println("ERROR: Can not open syntax specification: "+f); 169 } 170 else { 171 if (f.getAbsolutePath().equals(f.getPath())) { 172 throw new IllegalArgumentException ("File MUST have relative path (to make package name): "+f); 173 } 174 175 String clsName = f.getName(); int idx = clsName.indexOf("."); if (idx > 0) 178 clsName = clsName.substring(0, idx); 179 180 String pkgName = f.getParent(); if (pkgName != null) { 182 if (pkgName.endsWith(File.separator)) 183 pkgName = pkgName.substring(0, pkgName.length() - 1); 184 pkgName = pkgName.replace(File.separatorChar, '.'); 185 } 186 187 try { 188 SyntaxBuilder builder = new SyntaxBuilder(new File(args[i])); 189 if (semantic) { 190 Syntax syntax = builder.getParserSyntax(); 191 generateSemanticSkeleton(syntax, clsName, pkgName); 192 } 193 else 194 if (type != null) { 195 Syntax syntax = builder.getParserSyntax(); 196 AbstractParserTables pt = type.equals("SLR") 197 ? new SLRParserTables(syntax) 198 : type.equals("LR") 199 ? new LRParserTables(syntax) 200 : new LALRParserTables(syntax); 201 generateParserTable(pt, clsName, pkgName); 202 } 203 else { 204 Syntax syntax = builder.getSyntax(); 205 generateSyntaxImpl(syntax, clsName, pkgName, builder.getInitialNonterminals()); 206 } 207 } 208 catch (Exception e) { 209 e.printStackTrace(); 210 } 211 } 212 } 213 } 214 } 215 216 } 217 | Popular Tags |