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