X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.graph.compiler%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Fcompiler%2Finternal%2Fparsing%2FParsing.java;fp=bundles%2Forg.simantics.graph.compiler%2Fsrc%2Forg%2Fsimantics%2Fgraph%2Fcompiler%2Finternal%2Fparsing%2FParsing.java;h=ab179fa67430597a58bc9f748e722b6fc9fea09b;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/internal/parsing/Parsing.java b/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/internal/parsing/Parsing.java new file mode 100644 index 000000000..ab179fa67 --- /dev/null +++ b/bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/internal/parsing/Parsing.java @@ -0,0 +1,237 @@ +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)); + } + } + +}