package org.simantics.graph.compiler.internal.parsing; import gnu.trove.map.hash.THashMap; import gnu.trove.procedure.TObjectIntProcedure; import gnu.trove.procedure.TObjectObjectProcedure; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.concurrent.Callable; import java.util.concurrent.Future; import org.antlr.runtime.ANTLRStringStream; import org.antlr.runtime.CharStream; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.RecognitionException; import org.antlr.runtime.TokenStream; import org.antlr.runtime.tree.Tree; import org.simantics.graph.compiler.SourceInfo.SourceFile; import org.simantics.graph.compiler.SourceInfo.Variable; import org.simantics.graph.compiler.internal.parsing.GraphParser.file_return; import org.simantics.graph.compiler.internal.parsing.SourceSplitter.SplitPoint; import org.simantics.graph.compiler.internal.store.VariableStore; import org.simantics.graph.compiler.internal.translation.GraphTranslator; import org.simantics.graph.query.Paths; import org.simantics.graph.store.GraphStore; import org.simantics.graph.utils.GraphExecutor; import org.simantics.ltk.ISource; import org.simantics.ltk.Location; import org.simantics.ltk.Problem; import org.simantics.ltk.SourcePart; import org.simantics.ltk.antlr.ANTLRUtils; public class Parsing implements Runnable { Collection sources; Collection errors; GraphStore store; Paths paths; public Parsing(Paths paths, Collection sources, Collection errors, GraphStore store) { this.paths = paths; this.sources = sources; this.errors = errors; this.store = store; } private static class ParsingResult { ISource source; Tree tree; public ParsingResult(ISource source, Tree tree) { this.source = source; this.tree = tree; } } public static byte[] read(ISource source) throws IOException { int length = source.length(); if(length >= 0) { byte[] buffer = new byte[length]; InputStream stream = source.open(); int pos = 0; while(pos < buffer.length) { int c = stream.read(buffer, pos, buffer.length-pos); if(c <= 0) break; pos += c; } stream.close(); return buffer; } else { byte[] buffer = new byte[1024]; InputStream stream = source.open(); int pos = 0; while(true) { int count = stream.read(buffer, pos, buffer.length-pos); if(count <= 0) break; pos += count; if(pos == buffer.length) buffer = Arrays.copyOf(buffer, buffer.length*2); } stream.close(); if(pos < buffer.length) buffer = Arrays.copyOf(buffer, pos); return buffer; } } @Override public void run() { try { ArrayList orderedSources = new ArrayList(sources); Collections.sort(orderedSources, new Comparator() { @Override public int compare(ISource o1, ISource o2) { return o1.getName().compareTo(o2.getName()); } }); ArrayList> parsingFutures = new ArrayList>(); //System.out.println("--"); for(ISource source : orderedSources) { String sourceString = new String(read(source), "UTF-8"); ArrayList splitPoints = SourceSplitter.split(sourceString, 6400); //System.out.println(splitPoints.size()-1); for(int i=1;i() { @Override public ParsingResult call() throws Exception { CharStream stream = new ANTLRStringStream(sourcePartString); GraphLexer lexer = new GraphLexer(stream) { @Override public void reportError(RecognitionException e) { synchronized(errors) { errors.add(ANTLRUtils.error(sourcePart, e, this)); } } }; TokenStream tokenStream = new CommonTokenStream(lexer); GraphParser parser = new GraphParser(tokenStream) { @Override public void reportError(RecognitionException e) { synchronized(errors) { errors.add(ANTLRUtils.error(sourcePart, e, this)); } } }; //long begin = System.nanoTime(); file_return result = parser.file(); //long end = System.nanoTime(); if(!errors.isEmpty()) return null; /*double time = (end-begin)*1e-6; if(time > 200.0) { System.out.println(time + " ms, size " + sourcePartString.length()); System.out.print(sourcePartString); }*/ return new ParsingResult(sourcePart, (Tree)result.getTree()); } })); } } /* * We want to add graphs to the store in a fixed order and therefore * we do not do this part in the same order as the parsing tasks * complete. */ THashMap translators = new THashMap(); for(Future future : parsingFutures) { ParsingResult result = future.get(); synchronized(errors) { if(!errors.isEmpty()) continue; } // Translate AST to statements //long beginTime = System.nanoTime(); ISource originalSource = ((SourcePart)result.source).getOriginalSource(); GraphTranslator translator = translators.get(originalSource); if(translator == null) { translator = new GraphTranslator(paths, errors, store); translators.put(originalSource, translator); } translator.setSource(result.source); translator.translateGraph(result.tree); /*long endTime = System.nanoTime(); reportTime("Trans " + result.source.getName(), beginTime, endTime); */ } /*for(ISource source : orderedSources) { System.out.println(source.getName()); GraphTranslator translator = translators.get(source); translator.getVariables().forEachEntry(new TObjectIntProcedure() { @Override public boolean execute(String a, int b) { System.out.println(" " + a + " " + b); return true; } }); }*/ final VariableStore variableStore = new VariableStore(); store.addStore(VariableStore.class, variableStore); translators.forEachEntry(new TObjectObjectProcedure() { @Override public boolean execute(ISource a, GraphTranslator b) { final ArrayList variables = new ArrayList(); b.getVariables().forEachEntry(new TObjectIntProcedure() { @Override public boolean execute(String a, int b) { variables.add(new Variable(a, b)); return true; } }); variableStore.addSourceFile( new SourceFile(a.getName(), variables, b.getDefinitionPositions())); return true; } }); } catch(Exception e) { e.printStackTrace(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); e.printStackTrace(new PrintStream(stream)); String description = "Internal error: " + new String(stream.toByteArray()); for(ISource source : sources) errors.add(new Problem(new Location(source), description)); } } }