Put a PYACC.SymbolRef inside PYACC.Production.SymbolRef to do the heavy lifting,...
authorNick Downing <downing.nick@gmail.com>
Sun, 29 Jul 2018 01:37:16 +0000 (11:37 +1000)
committerNick Downing <downing.nick@gmail.com>
Sun, 29 Jul 2018 01:43:55 +0000 (11:43 +1000)
ast.py

diff --git a/ast.py b/ast.py
index e68f830..8a89e5c 100644 (file)
--- a/ast.py
+++ b/ast.py
@@ -637,7 +637,8 @@ class PYACC(element.Element):
         name_to_tag,
         last_action
       ):
-        self[0].post_process(
+        assert production.precedence_terminal == -1
+        _, production.precedence_terminal = self[0].post_process(
           pyacc,
           section,
           character_to_symbol,
@@ -648,8 +649,6 @@ class PYACC(element.Element):
           -1, # _tag
           -1 # precedence
         )
-        assert production.precedence_terminal == -1
-        production.precedence_terminal = self[0].symbol
         return last_action
 
     class SymbolRef(Item):
@@ -698,7 +697,6 @@ class PYACC(element.Element):
         self.repr_serialize(params)
         return 'ast.PYACC.Production.SymbolRef({0:s})'.format(', '.join(params))
       # GENERATE END
-
       def post_process(
         self,
         pyacc,
@@ -712,48 +710,20 @@ class PYACC(element.Element):
       ):
         pyacc.n_productions += int(last_action) # midrule action production
         production.n_symbols += int(last_action) + 1 # midrule action symbol
-        if isinstance(self[0], PYACC.Char):
-          character = ord(self[0][0].get_text())
-          assert character != 0 # would conflict with YYEOF
-          if character in character_to_symbol:
-            self.symbol = character_to_symbol[character]
-            assert (
-              pyacc.symbols[self.symbol]._type == PYACC.Symbol.TYPE_TERMINAL
-            )
-          else:
-            self.symbol = len(pyacc.symbols)
-            character_to_symbol[character] = self.symbol
-            pyacc.symbols.append(
-              PYACC.Symbol(
-                code_props = [None, None],
-                _type = PYACC.Symbol.TYPE_TERMINAL,
-                character_set = [character, character + 1]
-              )
-            )
-        elif isinstance(self[0], PYACC.ID):
-          name = self[0].get_text()
-          if name in name_to_symbol:
-            self.symbol = name_to_symbol[name]
-          else:
-            self.symbol = len(pyacc.symbols)
-            name_to_symbol[name] = self.symbol
-            pyacc.symbols.append(
-              PYACC.Symbol(
-                name = name,
-                code_props = [None, None],
-                _type = PYACC.Symbol.TYPE_NONTERMINAL,
-                character_set = []
-              )
-            )
-        elif isinstance(self[0], PYACC.String):
-          string = self[0][0].get_text()
-          self.symbol = string_to_symbol[string] # must already exist
-        else:
-          assert False
+        _, self.symbol = self[0].post_process(
+          pyacc,
+          section,
+          character_to_symbol,
+          name_to_symbol,
+          string_to_symbol,
+          name_to_tag,
+          -1, # _type
+          -1, # _tag
+          -1 # precedence
+        )
         if pyacc.symbols[self.symbol]._type == PYACC.Symbol.TYPE_TERMINAL:
           production.last_terminal = self.symbol
         return False
-
       def add_to_symbols(
         self,
         pyacc,
@@ -1146,7 +1116,7 @@ class PYACC(element.Element):
       ):
         _tag = -1
         for i in self:
-          _tag = i.post_process(
+          _tag, _ = i.post_process(
             pyacc,
             section,
             character_to_symbol,
@@ -1215,7 +1185,7 @@ class PYACC(element.Element):
       ):
         _tag = -1
         for i in self:
-          _tag = i.post_process(
+          _tag, _ = i.post_process(
             pyacc,
             section,
             character_to_symbol,
@@ -1264,7 +1234,7 @@ class PYACC(element.Element):
         string_to_symbol,
         name_to_tag
       ):
-        self[0].post_process(
+        _, pyacc.start_nonterminal = self[0].post_process(
           pyacc,
           section,
           character_to_symbol,
@@ -1275,7 +1245,6 @@ class PYACC(element.Element):
           -1, # _tag
           -1 # precedence
         )
-        pyacc.start_nonterminal = self[0].symbol
 
     class Token(Item):
       # GENERATE ELEMENT() BEGIN
@@ -1315,7 +1284,7 @@ class PYACC(element.Element):
       ):
         _tag = -1
         for i in self:
-          _tag = i.post_process(
+          _tag, _ = i.post_process(
             pyacc,
             section,
             character_to_symbol,
@@ -1365,7 +1334,7 @@ class PYACC(element.Element):
       ):
         _tag = -1
         for i in self:
-          _tag = i.post_process(
+          _tag, _ = i.post_process(
             pyacc,
             section,
             character_to_symbol,
@@ -2386,7 +2355,7 @@ class PYACC(element.Element):
         string_to_symbol,
         name_to_tag
       ):
-        self[0].post_process(
+        _, lhs_nonterminal = self[0].post_process(
           pyacc,
           section,
           character_to_symbol,
@@ -2398,12 +2367,12 @@ class PYACC(element.Element):
           -1 # precedence
         )
         if pyacc.first_nonterminal == -1:
-          pyacc.first_nonterminal = self[0].symbol
+          pyacc.first_nonterminal = lhs_nonterminal
         for i in self[1:]:
           i.post_process(
             pyacc,
             section,
-            self[0].symbol,
+            lhs_nonterminal,
             character_to_symbol,
             name_to_symbol,
             string_to_symbol,
@@ -2519,14 +2488,13 @@ class PYACC(element.Element):
       raise NotImplementedError
 
   class TagRef(TagOrSymbolRef):
-    # GENERATE ELEMENT(int _tag) BEGIN
+    # GENERATE ELEMENT() BEGIN
     def __init__(
       self,
       tag = 'PYACC_TagRef',
       attrib = {},
       text = '',
-      children = [],
-      _tag = -1
+      children = []
     ):
       PYACC.TagOrSymbolRef.__init__(
         self,
@@ -2535,30 +2503,12 @@ class PYACC(element.Element):
         text,
         children
       )
-      self._tag = (
-        element.deserialize_int(_tag)
-      if isinstance(_tag, str) else
-        _tag
-      )
-    def serialize(self, ref_list):
-      PYACC.TagOrSymbolRef.serialize(self, ref_list)
-      self.set('_tag', element.serialize_int(self._tag))
-    def deserialize(self, ref_list):
-      PYACC.TagOrSymbolRef.deserialize(self, ref_list)
-      self._tag = element.deserialize_int(self.get('_tag', '-1'))
     def copy(self, factory = None):
       result = PYACC.TagOrSymbolRef.copy(
         self,
         TagRef if factory is None else factory
       )
-      result._tag = self._tag
       return result
-    def repr_serialize(self, params):
-      PYACC.TagOrSymbolRef.repr_serialize(self, params)
-      if self._tag != -1:
-        params.append(
-          '_tag = {0:s}'.format(repr(self._tag))
-        )
     def __repr__(self):
       params = []
       self.repr_serialize(params)
@@ -2578,14 +2528,14 @@ class PYACC(element.Element):
     ):
       name = self[0].get_text()
       if name in name_to_tag:
-        self._tag = name_to_tag[name]
+        _tag = name_to_tag[name]
       else:
-        self._tag = len(pyacc.tags)
-        name_to_tag[name] = self._tag
+        _tag = len(pyacc.tags)
+        name_to_tag[name] = _tag
         pyacc.tags.append(
           PYACC.Tag(name = name, code_props = [None, None])
         )
-      return self._tag
+      return (_tag, -1)
     def set_code_props(
       self,
       pyacc,
@@ -2599,26 +2549,25 @@ class PYACC(element.Element):
     ):
       name = self[0].get_text()
       if name in name_to_tag:
-        self._tag = name_to_tag[name]
+        _tag = name_to_tag[name]
       else:
-        self._tag = len(pyacc.tags)
-        name_to_tag[name] = self._tag
+        _tag = len(pyacc.tags)
+        name_to_tag[name] = _tag
         pyacc.tags.append(
           PYACC.Tag(name = name, code_props = [None, None])
         )
-      assert pyacc.tags[self._tag].code_props[_type] is None
-      pyacc.tags[self._tag].code_props[_type] = code
+      assert pyacc.tags[_tag].code_props[_type] is None
+      pyacc.tags[_tag].code_props[_type] = code
 
   class SymbolRef(TagOrSymbolRef):
-    # GENERATE ELEMENT(int user_token, int symbol) BEGIN
+    # GENERATE ELEMENT(int user_token) BEGIN
     def __init__(
       self,
       tag = 'PYACC_SymbolRef',
       attrib = {},
       text = '',
       children = [],
-      user_token = -1,
-      symbol = -1
+      user_token = -1
     ):
       PYACC.TagOrSymbolRef.__init__(
         self,
@@ -2632,26 +2581,18 @@ class PYACC(element.Element):
       if isinstance(user_token, str) else
         user_token
       )
-      self.symbol = (
-        element.deserialize_int(symbol)
-      if isinstance(symbol, str) else
-        symbol
-      )
     def serialize(self, ref_list):
       PYACC.TagOrSymbolRef.serialize(self, ref_list)
       self.set('user_token', element.serialize_int(self.user_token))
-      self.set('symbol', element.serialize_int(self.symbol))
     def deserialize(self, ref_list):
       PYACC.TagOrSymbolRef.deserialize(self, ref_list)
       self.user_token = element.deserialize_int(self.get('user_token', '-1'))
-      self.symbol = element.deserialize_int(self.get('symbol', '-1'))
     def copy(self, factory = None):
       result = PYACC.TagOrSymbolRef.copy(
         self,
         SymbolRef if factory is None else factory
       )
       result.user_token = self.user_token
-      result.symbol = self.symbol
       return result
     def repr_serialize(self, params):
       PYACC.TagOrSymbolRef.repr_serialize(self, params)
@@ -2659,10 +2600,6 @@ class PYACC(element.Element):
         params.append(
           'user_token = {0:s}'.format(repr(self.user_token))
         )
-      if self.symbol != -1:
-        params.append(
-          'symbol = {0:s}'.format(repr(self.symbol))
-        )
     def __repr__(self):
       params = []
       self.repr_serialize(params)
@@ -2684,10 +2621,10 @@ class PYACC(element.Element):
         character = ord(self[0][0].get_text())
         assert character != 0 # would conflict with YYEOF
         if character in character_to_symbol:
-          self.symbol = character_to_symbol[character]
+          symbol = character_to_symbol[character]
         else:
-          self.symbol = len(pyacc.symbols)
-          character_to_symbol[character] = self.symbol
+          symbol = len(pyacc.symbols)
+          character_to_symbol[character] = symbol
           pyacc.symbols.append(
             PYACC.Symbol(
               code_props = [None, None],
@@ -2698,10 +2635,10 @@ class PYACC(element.Element):
       elif isinstance(self[0], PYACC.ID):
         name = self[0].get_text()
         if name in name_to_symbol:
-          self.symbol = name_to_symbol[name]
+          symbol = name_to_symbol[name]
         else:
-          self.symbol = len(pyacc.symbols)
-          name_to_symbol[name] = self.symbol
+          symbol = len(pyacc.symbols)
+          name_to_symbol[name] = symbol
           pyacc.symbols.append(
             PYACC.Symbol(
               name = name,
@@ -2711,35 +2648,35 @@ class PYACC(element.Element):
           )
       elif isinstance(self[0], PYACC.String):
         string = self[0][0].get_text()
-        self.symbol = string_to_symbol[string] # must already exist
+        symbol = string_to_symbol[string] # must already exist
       else:
         assert False
 
       # insert information from the SymbolRef element
       if self.user_token != -1:
-        assert len(pyacc.symbols[self.symbol].character_set) == 0
-        pyacc.symbols[self.symbol].character_set = (
+        assert len(pyacc.symbols[symbol].character_set) == 0
+        pyacc.symbols[symbol].character_set = (
           [self.user_token, self.user_token + 1]
         )
       if len(self) >= 2:
         string = self[1][0].get_text()
         assert string not in string_to_symbol
-        string_to_symbol[string] = self.symbol
+        string_to_symbol[string] = symbol
 
       # insert information from the calling contexxt
       if _type != -1:
-        if pyacc.symbols[self.symbol]._type == -1:
-          pyacc.symbols[self.symbol]._type = _type
+        if pyacc.symbols[symbol]._type == -1:
+          pyacc.symbols[symbol]._type = _type
         else:
-          assert pyacc.symbols[self.symbol]._type == _type
+          assert pyacc.symbols[symbol]._type == _type
       if _tag != -1:
-        assert pyacc.symbols[self.symbol]._tag == -1
-        pyacc.symbols[self.symbol]._tag = _tag
+        assert pyacc.symbols[symbol]._tag == -1
+        pyacc.symbols[symbol]._tag = _tag
       if precedence != -1:
-        assert pyacc.symbols[self.symbol].precedence == -1
-        pyacc.symbols[self.symbol].precedence = precedence
+        assert pyacc.symbols[symbol].precedence == -1
+        pyacc.symbols[symbol].precedence = precedence
 
-      return _tag
+      return (_tag, symbol)
 
     def set_code_props(
       self,
@@ -2756,14 +2693,14 @@ class PYACC(element.Element):
         character = ord(self[0][0].get_text())
         assert character != 0 # would conflict with YYEOF
         if character in character_to_symbol:
-          self.symbol = character_to_symbol[character]
+          symbol = character_to_symbol[character]
           assert (
-            pyacc.symbols[self.symbol]._type ==
+            pyacc.symbols[symbol]._type ==
             PYACC.Symbol.TYPE_TERMINAL
           )
         else:
-          self.symbol = len(pyacc.symbols)
-          character_to_symbol[character] = self.symbol
+          symbol = len(pyacc.symbols)
+          character_to_symbol[character] = symbol
           pyacc.symbols.append(
             PYACC.Symbol(
               code_props = [None, None],
@@ -2773,14 +2710,14 @@ class PYACC(element.Element):
           )
       elif isinstance(self[0], PYACC.ID):
         name = self[0].get_text()
-        self.symbol = name_to_symbol[name] # must already exist
+        symbol = name_to_symbol[name] # must already exist
       elif isinstance(self[0], PYACC.String):
         string = self[0][0].get_text()
-        self.symbol = string_to_symbol[string] # must already exist
+        symbol = string_to_symbol[string] # must already exist
       else:
         assert False
-      assert pyacc.symbols[self.symbol].code_props[_type] is None
-      pyacc.symbols[self.symbol].code_props[_type] = code
+      assert pyacc.symbols[symbol].code_props[_type] is None
+      pyacc.symbols[symbol].code_props[_type] = code
 
   class Text(element.Element):
     class Item(element.Element):