package org.simantics.scl.compiler.parser.generator.java; import gnu.trove.set.hash.THashSet; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.simantics.scl.compiler.parser.generator.compression.CompressedParseTable; import org.simantics.scl.compiler.parser.generator.grammar.AnaGrammar; import org.simantics.scl.compiler.parser.generator.grammar.Prod; public class GenerateParser { String packageName; String className; String exceptionName; AnaGrammar grammar; CompressedParseTable table; public GenerateParser(String packageName, String className, AnaGrammar grammar, String exceptionName, CompressedParseTable table) { this.packageName = packageName; this.className = className; this.grammar = grammar; this.exceptionName = exceptionName; this.table = table; } private String readTemplate() throws IOException { InputStream stream = getClass().getResourceAsStream("Parser.java.template"); byte[] buffer = new byte[10000]; int pos = 0; while(true) { int c = stream.read(buffer, pos, buffer.length-pos); if(c <= 0) break; pos += c; if(pos == buffer.length) buffer = Arrays.copyOf(buffer, buffer.length*2); } return new String(buffer, 0, pos, "UTF-8"); } private static final Pattern PATTERN = Pattern.compile("\\$[A-Za-z0-9]+\\$"); public void generate(File file) throws IOException { PrintStream out = new PrintStream(file, "UTF-8"); int aPos = 0; String template = readTemplate(); Matcher matcher = PATTERN.matcher(template); while(matcher.find()) { int start = matcher.start(); int end = matcher.end(); out.print(template.substring(aPos, start)); String varName = template.substring(start+1, end-1); generateVar(out, varName); aPos = end; } out.print(template.substring(aPos)); out.close(); } private void generateVar(PrintStream out, String varName) { if("package".equals(varName)) { out.print(packageName); } else if("class".equals(varName)) { out.print(className); } else if("terminalCount".equals(varName)) { out.print(grammar.terminalNames.length); } else if("nonterminalCount".equals(varName)) { out.print(grammar.nonterminalNames.length); } else if("productCount".equals(varName)) { out.print(grammar.prods.size()); } else if("stateCount".equals(varName)) { out.print(table.actionTable.rowIndex.length); } else if("parseMethods".equals(varName)) { for(int i=0;i 0) out.println(","); out.print(" \"" + grammar.terminalNames[i] + "\""); } } else if("nonterminalNames".equals(varName)) { for(int i=0;i 0) out.println(","); out.print(" \"" + grammar.nonterminalNames[i] + "\""); } } else if("stateDescriptions".equals(varName)) { for(int i=0;i 0) out.println(","); out.print(" \"" + table.stateDescriptions[i].replace("\n", "\\n") + "\""); } } else if("reduceCases".equals(varName)) { for(int i=0;i usedNames = new THashSet(); for(int i=0;i