Get rid of set_code_props() in favour of the ordinary post_process(), fix union
authorNick Downing <downing.nick@gmail.com>
Sun, 29 Jul 2018 01:54:48 +0000 (11:54 +1000)
committerNick Downing <downing.nick@gmail.com>
Sun, 29 Jul 2018 01:54:48 +0000 (11:54 +1000)
ast.py
bison_lr1dfa.py

diff --git a/ast.py b/ast.py
index 8a89e5c..40155bf 100644 (file)
--- a/ast.py
+++ b/ast.py
@@ -973,7 +973,7 @@ class PYACC(element.Element):
         if len(name) == 0: # do the same as Section1.Prologue
           (
             pyacc.before_union_code
-          if pyacc.union_code is None else
+          if len(pyacc.union_code) == 0 else
             pyacc.after_union_code
           ).append(self[1])
         elif name == 'top':
@@ -1039,16 +1039,20 @@ class PYACC(element.Element):
         name_to_tag
       ):
         for i in self[1:]:
-          i.set_code_props(
+          _, j = i.post_process(
             pyacc,
             section,
             character_to_symbol,
             name_to_symbol,
             string_to_symbol,
             name_to_tag,
-            self._type, # _type
-            self[0] # code
+            -1, # _type
+            -1, # _tag
+            -1 # precedence
           )
+          tag_or_symbol = pyacc.symbols[j] if j >= 0 else pyacc.tags[~j]
+          assert tag_or_symbol.code_props[self._type] is None
+          tag_or_symbol.code_props[self._type] = self[0]
 
     class DefaultPrec(Item):
       # GENERATE ELEMENT() BEGIN
@@ -1382,10 +1386,11 @@ class PYACC(element.Element):
         string_to_symbol,
         name_to_tag
       ):
-        assert len(pyacc.union_name) == 0 # fix this later
-        pyacc.union_name = self[0].get_text()
-        assert pyacc.union_code is None # fix this later
-        pyacc.union_code = self[1] 
+        name = self[0].get_text()
+        if len(name):
+          assert len(pyacc.union_name) == 0
+          pyacc.union_name = name
+        pyacc.union_code.append(self[1])
 
     # GENERATE ELEMENT() BEGIN
     def __init__(
@@ -1987,7 +1992,7 @@ class PYACC(element.Element):
       ):
         (
           pyacc.before_union_code
-        if pyacc.union_code is None else
+        if len(pyacc.union_code) == 0 else
           pyacc.after_union_code
         ).append(self[0])
 
@@ -2474,18 +2479,6 @@ class PYACC(element.Element):
       precedence
     ):
       raise NotImplementedError
-    def set_code_props(
-      self,
-      pyacc,
-      section,
-      character_to_symbol,
-      name_to_symbol,
-      string_to_symbol,
-      name_to_tag,
-      _type,
-      code
-    ):
-      raise NotImplementedError
 
   class TagRef(TagOrSymbolRef):
     # GENERATE ELEMENT() BEGIN
@@ -2535,29 +2528,7 @@ class PYACC(element.Element):
         pyacc.tags.append(
           PYACC.Tag(name = name, code_props = [None, None])
         )
-      return (_tag, -1)
-    def set_code_props(
-      self,
-      pyacc,
-      section,
-      character_to_symbol,
-      name_to_symbol,
-      string_to_symbol,
-      name_to_tag,
-      _type,
-      code
-    ):
-      name = self[0].get_text()
-      if name in name_to_tag:
-        _tag = name_to_tag[name]
-      else:
-        _tag = len(pyacc.tags)
-        name_to_tag[name] = _tag
-        pyacc.tags.append(
-          PYACC.Tag(name = name, code_props = [None, None])
-        )
-      assert pyacc.tags[_tag].code_props[_type] is None
-      pyacc.tags[_tag].code_props[_type] = code
+      return (_tag, ~_tag)
 
   class SymbolRef(TagOrSymbolRef):
     # GENERATE ELEMENT(int user_token) BEGIN
@@ -2678,47 +2649,6 @@ class PYACC(element.Element):
 
       return (_tag, symbol)
 
-    def set_code_props(
-      self,
-      pyacc,
-      section,
-      character_to_symbol,
-      name_to_symbol,
-      string_to_symbol,
-      name_to_tag,
-      _type,
-      code
-    ):
-      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:
-          symbol = character_to_symbol[character]
-          assert (
-            pyacc.symbols[symbol]._type ==
-            PYACC.Symbol.TYPE_TERMINAL
-          )
-        else:
-          symbol = len(pyacc.symbols)
-          character_to_symbol[character] = 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()
-        symbol = name_to_symbol[name] # must already exist
-      elif isinstance(self[0], PYACC.String):
-        string = self[0][0].get_text()
-        symbol = string_to_symbol[string] # must already exist
-      else:
-        assert False
-      assert pyacc.symbols[symbol].code_props[_type] is None
-      pyacc.symbols[symbol].code_props[_type] = code
-
   class Text(element.Element):
     class Item(element.Element):
       # GENERATE ELEMENT() BEGIN
@@ -3145,7 +3075,7 @@ class PYACC(element.Element):
     ):
       pass
 
-  # GENERATE ELEMENT(list(ref) top_code, list(ref) before_union_code, list(ref) requires_code, str union_name, ref union_code, list(ref) after_union_code, ref initial_action_code, list(ref) tags, list(ref) symbols, int n_productions, list(ref) productions, int first_nonterminal, int start_nonterminal, list(int) associativities) BEGIN
+  # GENERATE ELEMENT(list(ref) top_code, list(ref) before_union_code, list(ref) requires_code, str union_name, list(ref) union_code, list(ref) after_union_code, ref initial_action_code, list(ref) tags, list(ref) symbols, int n_productions, list(ref) productions, int first_nonterminal, int start_nonterminal, list(int) associativities) BEGIN
   def __init__(
     self,
     tag = 'PYACC',
@@ -3156,7 +3086,7 @@ class PYACC(element.Element):
     before_union_code = [],
     requires_code = [],
     union_name = '',
-    union_code = None,
+    union_code = [],
     after_union_code = [],
     initial_action_code = None,
     tags = [],
@@ -3219,7 +3149,10 @@ class PYACC(element.Element):
       ' '.join([element.serialize_ref(i, ref_list) for i in self.requires_code])
     )
     self.set('union_name', element.serialize_str(self.union_name))
-    self.set('union_code', element.serialize_ref(self.union_code, ref_list))
+    self.set(
+      'union_code',
+      ' '.join([element.serialize_ref(i, ref_list) for i in self.union_code])
+    )
     self.set(
       'after_union_code',
       ' '.join([element.serialize_ref(i, ref_list) for i in self.after_union_code])
@@ -3259,7 +3192,10 @@ class PYACC(element.Element):
       for i in self.get('requires_code', '').split()
     ]
     self.union_name = element.deserialize_str(self.get('union_name', ''))
-    self.union_code = element.deserialize_ref(self.get('union_code', '-1'), ref_list)
+    self.union_code = [
+      element.deserialize_ref(i, ref_list)
+      for i in self.get('union_code', '').split()
+    ]
     self.after_union_code = [
       element.deserialize_ref(i, ref_list)
       for i in self.get('after_union_code', '').split()
@@ -3328,9 +3264,11 @@ class PYACC(element.Element):
       params.append(
         'union_name = {0:s}'.format(repr(self.union_name))
       )
-    if self.union_code != None:
+    if len(self.union_code):
       params.append(
-        'union_code = {0:s}'.format(repr(self.union_code))
+        'union_code = [{0:s}]'.format(
+          ', '.join([repr(i) for i in self.union_code])
+        )
       )
     if len(self.after_union_code):
       params.append(
@@ -3390,7 +3328,7 @@ class PYACC(element.Element):
     self.before_union_code = []
     self.requires_code = []
     self.union_name = ''
-    self.union_code = None
+    self.union_code = []
     self.after_union_code = []
     self.initial_action_code = None
     self.precedences = 0
index d9526df..90ded8a 100644 (file)
@@ -393,14 +393,14 @@ def generate(pyacc, skel_file, out_file, defines_file = None):
 typedef int YYSTYPE;
 /* GENERATE UNION END */
 '''
-              if pyacc.union_code is None else
+              if len(pyacc.union_code) == 0 else
                 '''/* GENERATE UNION BEGIN */
 union YYSTYPE
 {0:s};
 typedef union YYSTYPE YYSTYPE;
 /* GENERATE UNION END */
 '''.format(
-                  pyacc.union_code.get_text()
+                  ''.join([i.get_text() for i in pyacc.union_code])
                 )
             )
           elif line == '/* GENERATE SECTION1AFTERUNION */\n':