Author: Carl Friedrich Bolz-Tereick <cfb...@gmx.de>
Branch: pyparser-improvements
Changeset: r93973:dde9199be301
Date: 2018-03-12 14:48 +0100
http://bitbucket.org/pypy/pypy/changeset/dde9199be301/

Log:    use a chained stack instead of list-of-tuples

diff --git a/pypy/interpreter/pyparser/parser.py 
b/pypy/interpreter/pyparser/parser.py
--- a/pypy/interpreter/pyparser/parser.py
+++ b/pypy/interpreter/pyparser/parser.py
@@ -181,12 +181,25 @@
         return "ParserError(%s, %r)" % (self.token_type, self.value)
 
 
+class StackEntry(object):
+    def __init__(self, next, dfa, state, node):
+        self.next = next
+        self.dfa = dfa
+        self.state = state
+        self.node = node
+
+    def push(self, dfa, state, node):
+        return StackEntry(self, dfa, state, node)
+
+    def pop(self):
+        return self.next
+
+
 class Parser(object):
 
     def __init__(self, grammar):
         self.grammar = grammar
         self.root = None
-        self.stack = None
 
     def prepare(self, start=-1):
         """Setup the parser for parsing.
@@ -197,14 +210,14 @@
             start = self.grammar.start
         self.root = None
         current_node = Nonterminal(start, [])
-        self.stack = []
-        self.stack.append((self.grammar.dfas[start - 256], 0, current_node))
+        self.stack = StackEntry(None, self.grammar.dfas[start - 256], 0, 
current_node)
 
     def add_token(self, token_type, value, lineno, column, line):
         label_index = self.classify(token_type, value, lineno, column, line)
         sym_id = 0 # for the annotator
         while True:
-            dfa, state_index, node = self.stack[-1]
+            dfa = self.stack.dfa
+            state_index = self.stack.state
             states, first = dfa
             arcs, is_accepting = states[state_index]
             for i, next_state in arcs:
@@ -217,10 +230,12 @@
                     # the stack.
                     while state[1] and not state[0]:
                         self.pop()
-                        if not self.stack:
+                        if self.stack is None:
+                            assert self.stack is None
                             # Parsing is done.
                             return True
-                        dfa, state_index, node = self.stack[-1]
+                        dfa = self.stack.dfa
+                        state_index = self.stack.state
                         state = dfa[0][state_index]
                     return False
                 elif sym_id >= 256:
@@ -235,7 +250,8 @@
                 # state is accepting, it's invalid input.
                 if is_accepting:
                     self.pop()
-                    if not self.stack:
+                    if self.stack is None:
+                        assert self.stack is None
                         raise ParseError("too much input", token_type, value,
                                          lineno, column, line)
                 else:
@@ -262,26 +278,27 @@
 
     def shift(self, next_state, token_type, value, lineno, column):
         """Shift a non-terminal and prepare for the next state."""
-        dfa, state, node = self.stack[-1]
         new_node = Terminal(token_type, value, lineno, column)
-        node.append_child(new_node)
-        self.stack[-1] = (dfa, next_state, node)
+        self.stack.node.append_child(new_node)
+        self.stack.state = next_state
 
     def push(self, next_dfa, next_state, node_type, lineno, column):
         """Push a terminal and adjust the current state."""
-        dfa, state, node = self.stack[-1]
         new_node = Nonterminal(node_type, [])
-        self.stack[-1] = (dfa, next_state, node)
-        self.stack.append((next_dfa, 0, new_node))
+
+        self.stack.state = next_state
+        self.stack = self.stack.push(next_dfa, 0, new_node)
 
     def pop(self):
         """Pop an entry off the stack and make its node a child of the last."""
-        dfa, state, node = self.stack.pop()
+        top = self.stack
+        self.stack = top.pop()
+        node = top.node
         if self.stack:
             # we are now done with node, so we can store it more efficiently if
             # it has just one child
             if node.num_children() == 1:
                 node = Nonterminal1(node.type, node.get_child(0))
-            self.stack[-1][2].append_child(node)
+            self.stack.node.append_child(node)
         else:
             self.root = node
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to