Ver código fonte

Optimize the convertToLineColumn function to remove quadratic complexity in compilation

Yentl Van Tendeloo 8 anos atrás
pai
commit
d1b80fa2f5
1 arquivos alterados com 26 adições e 19 exclusões
  1. 26 19
      interface/HUTN/hutn_compiler/hutnparser.py

+ 26 - 19
interface/HUTN/hutn_compiler/hutnparser.py

@@ -329,31 +329,38 @@ class Parser(object):
                 result['tree'] = Parser.PositionPostProcessor(self.convertToLineColumn).visit(result['tree'])
         return result
 
-    def convertToLineColumn(self, pos):
+    def generate_line_cache(self):
+        global line_cache
+        if self in line_cache:
+            return
+
+        line_cache[self] = []
+
+        lc = line_cache[self]
+
+        l = len(self.input)
         line = 1
         column = 0
-        l = len(self.input)
-        for i in range(0, l):
-            if (i > pos):
-                break
-            if self.input[i] == '\n':
+        pos = 0
+
+        while pos < l:
+            if self.input[pos] == "\n":
                 line += 1
                 column = 0
-            elif self.input[i] == '\t':
-                column += self.tabsize #changed by Daniel: this used to be 4
+            elif self.input[pos] == "\t":
+                column += self.tabsize
             else:
                 column += 1
-        if pos >= l: #the end of the text
-            """
-            added by Daniel: needed for the case of the last word/character.
-            Assume a text on one word 'foo'
-            in absolute position the tree says word is from 1 to 4 (as always 'to' means not included)
-            in this method we only count until the range so we would return line 1 col 1 to line 1 col 3
-            but we need col 4
-            we could just says pos == l but i think its better to say any position bigger than the text is simply the end of the text
-            """
-            column += 1
-        return {'line': line, 'column': column}
+            lc.append((line, column))
+            pos += 1
+
+    def convertToLineColumn(self, pos):
+        global line_cache
+        self.generate_line_cache()
+        if pos > len(line_cache[self]):
+            return {'line': line_cache[self][pos][0], 'column': line_cache[self][pos][1]}
+        else:
+            return {'line': line_cache[self][-1][0], 'column': line_cache[self][-1][1] + 1}
 
     def findlargerresultat(self, pos):
         endpos = pos