Rationalize PYACC.Text so it occurs only once inside containers like PYACC.Char,...
authorNick Downing <downing.nick@gmail.com>
Thu, 19 Jul 2018 13:27:01 +0000 (23:27 +1000)
committerNick Downing <downing.nick@gmail.com>
Thu, 19 Jul 2018 13:27:01 +0000 (23:27 +1000)
ast.py
bison_lr1dfa.py

diff --git a/ast.py b/ast.py
index 70ef01e..7e494cf 100644 (file)
--- a/ast.py
+++ b/ast.py
@@ -188,49 +188,6 @@ class PYACC(element.Element):
     # GENERATE END
 
   # syntax classes
-  class BracedCode(element.Element):
-    # GENERATE ELEMENT() BEGIN
-    def __init__(
-      self,
-      tag = 'PYACC_BracedCode',
-      attrib = {},
-      text = '',
-      children = []
-    ):
-      element.Element.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-    def copy(self, factory = None):
-      result = element.Element.copy(
-        self,
-        BracedCode if factory is None else factory
-      )
-      return result
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.PYACC.BracedCode({0:s})'.format(', '.join(params))
-    # GENERATE END
-    def get_text(self, len_production = 0):
-      return ''.join(
-        [
-          (
-            '(yyvsp[{0:d}])'.format(i.index - len_production)
-          if isinstance(i, PYACC.StackReference) else
-            '(yyval)'
-          if isinstance(i, PYACC.ValueReference) else
-            chr(i.character)
-          if isinstance(i, PYACC.Escape) else
-            element.get_text(i, 0)
-          )
-          for i in self
-        ]
-      )
-
   class BracedPredicate(element.Element):
     # GENERATE ELEMENT() BEGIN
     def __init__(
@@ -286,92 +243,6 @@ class PYACC(element.Element):
       self.repr_serialize(params)
       return 'ast.PYACC.Char({0:s})'.format(', '.join(params))
     # GENERATE END
-    def get_text(self):
-      return ''.join(
-        [
-          (
-            chr(i.character)
-          if isinstance(i, PYACC.Escape) else
-            element.get_text(i, 0)
-          )
-          for i in self
-        ]
-      )
-
-  class Escape(element.Element):
-    # GENERATE ELEMENT(int character) BEGIN
-    def __init__(
-      self,
-      tag = 'PYACC_Escape',
-      attrib = {},
-      text = '',
-      children = [],
-      character = -1
-    ):
-      element.Element.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-      self.character = (
-        element.deserialize_int(character)
-      if isinstance(character, str) else
-        character
-      )
-    def serialize(self, ref_list):
-      element.Element.serialize(self, ref_list)
-      self.set('character', element.serialize_int(self.character))
-    def deserialize(self, ref_list):
-      element.Element.deserialize(self, ref_list)
-      self.character = element.deserialize_int(self.get('character', '-1'))
-    def copy(self, factory = None):
-      result = element.Element.copy(
-        self,
-        Escape if factory is None else factory
-      )
-      result.character = self.character
-      return result
-    def repr_serialize(self, params):
-      element.Element.repr_serialize(self, params)
-      if self.character != -1:
-        params.append(
-          'character = {0:s}'.format(repr(self.character))
-        )
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.PYACC.Escape({0:s})'.format(', '.join(params))
-    # GENERATE END
-
-  class ID(element.Element):
-    # GENERATE ELEMENT() BEGIN
-    def __init__(
-      self,
-      tag = 'PYACC_ID',
-      attrib = {},
-      text = '',
-      children = []
-    ):
-      element.Element.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-    def copy(self, factory = None):
-      result = element.Element.copy(
-        self,
-        ID if factory is None else factory
-      )
-      return result
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.PYACC.ID({0:s})'.format(', '.join(params))
-    # GENERATE END
 
   class Int(element.Element):
     # GENERATE ELEMENT() BEGIN
@@ -685,7 +556,7 @@ class PYACC(element.Element):
         name_to_symbol
       ):
         if isinstance(self[0], PYACC.Char):
-          character = ord(self[0].get_text())
+          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]
@@ -697,7 +568,7 @@ class PYACC(element.Element):
               PYACC.Terminal(character_set = [character, character + 1])
             )
         elif isinstance(self[0], PYACC.ID):
-          name = element.get_text(self[0], 0)
+          name = self[0].get_text()
           if name in name_to_symbol:
             self.symbol = name_to_symbol[name]
           else:
@@ -886,100 +757,6 @@ class PYACC(element.Element):
     ):
       raise NotImplementedException
 
-  class StackLocation(element.Element):
-    # GENERATE ELEMENT(int index) BEGIN
-    def __init__(
-      self,
-      tag = 'PYACC_StackLocation',
-      attrib = {},
-      text = '',
-      children = [],
-      index = -1
-    ):
-      element.Element.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-      self.index = (
-        element.deserialize_int(index)
-      if isinstance(index, str) else
-        index
-      )
-    def serialize(self, ref_list):
-      element.Element.serialize(self, ref_list)
-      self.set('index', element.serialize_int(self.index))
-    def deserialize(self, ref_list):
-      element.Element.deserialize(self, ref_list)
-      self.index = element.deserialize_int(self.get('index', '-1'))
-    def copy(self, factory = None):
-      result = element.Element.copy(
-        self,
-        StackLocation if factory is None else factory
-      )
-      result.index = self.index
-      return result
-    def repr_serialize(self, params):
-      element.Element.repr_serialize(self, params)
-      if self.index != -1:
-        params.append(
-          'index = {0:s}'.format(repr(self.index))
-        )
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.PYACC.StackLocation({0:s})'.format(', '.join(params))
-    # GENERATE END
-
-  class StackReference(element.Element):
-    # GENERATE ELEMENT(int index) BEGIN
-    def __init__(
-      self,
-      tag = 'PYACC_StackReference',
-      attrib = {},
-      text = '',
-      children = [],
-      index = -1
-    ):
-      element.Element.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-      self.index = (
-        element.deserialize_int(index)
-      if isinstance(index, str) else
-        index
-      )
-    def serialize(self, ref_list):
-      element.Element.serialize(self, ref_list)
-      self.set('index', element.serialize_int(self.index))
-    def deserialize(self, ref_list):
-      element.Element.deserialize(self, ref_list)
-      self.index = element.deserialize_int(self.get('index', '-1'))
-    def copy(self, factory = None):
-      result = element.Element.copy(
-        self,
-        StackReference if factory is None else factory
-      )
-      result.index = self.index
-      return result
-    def repr_serialize(self, params):
-      element.Element.repr_serialize(self, params)
-      if self.index != -1:
-        params.append(
-          'index = {0:s}'.format(repr(self.index))
-        )
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.PYACC.StackReference({0:s})'.format(', '.join(params))
-    # GENERATE END
-
   class String(element.Element):
     # GENERATE ELEMENT() BEGIN
     def __init__(
@@ -1007,17 +784,6 @@ class PYACC(element.Element):
       self.repr_serialize(params)
       return 'ast.PYACC.String({0:s})'.format(', '.join(params))
     # GENERATE END
-    def get_text(self):
-      return ''.join(
-        [
-          (
-            chr(i.character)
-          if isinstance(i, PYACC.Escape) else
-            element.get_text(i, 0)
-          )
-          for i in self
-        ]
-      )
 
   class TagOrSymbolRef(element.Element):
     # GENERATE ELEMENT() BEGIN
@@ -1183,7 +949,7 @@ class PYACC(element.Element):
       tag
     ):
       if isinstance(self[0], PYACC.Char):
-        character = ord(self[0].get_text())
+        character = ord(self[0][0].get_text())
         assert character != 0 # would conflict with YYEOF
         if character in character_to_symbol:
           self.terminal = character_to_symbol[character]
@@ -1195,7 +961,7 @@ class PYACC(element.Element):
             PYACC.Terminal(character_set = [character, character + 1])
           )
       elif isinstance(self[0], PYACC.ID):
-        name = element.get_text(self[0], 0)
+        name = self[0].get_text()
         if name in name_to_symbol:
           self.terminal = name_to_symbol[name]
           assert self.terminal >= 0
@@ -1286,7 +1052,7 @@ class PYACC(element.Element):
       tag
     ):
       if isinstance(self[0], PYACC.ID):
-        name = element.get_text(self[0], 0)
+        name = self[0].get_text()
         if name in name_to_symbol:
           i = name_to_symbol[name]
           assert i < 0
@@ -1304,6 +1070,203 @@ class PYACC(element.Element):
       return tag
 
   class Text(element.Element):
+    class Escape(element.Element):
+      # GENERATE ELEMENT(int character) BEGIN
+      def __init__(
+        self,
+        tag = 'PYACC_Text_Escape',
+        attrib = {},
+        text = '',
+        children = [],
+        character = -1
+      ):
+        element.Element.__init__(
+          self,
+          tag,
+          attrib,
+          text,
+          children
+        )
+        self.character = (
+          element.deserialize_int(character)
+        if isinstance(character, str) else
+          character
+        )
+      def serialize(self, ref_list):
+        element.Element.serialize(self, ref_list)
+        self.set('character', element.serialize_int(self.character))
+      def deserialize(self, ref_list):
+        element.Element.deserialize(self, ref_list)
+        self.character = element.deserialize_int(self.get('character', '-1'))
+      def copy(self, factory = None):
+        result = element.Element.copy(
+          self,
+          Escape if factory is None else factory
+        )
+        result.character = self.character
+        return result
+      def repr_serialize(self, params):
+        element.Element.repr_serialize(self, params)
+        if self.character != -1:
+          params.append(
+            'character = {0:s}'.format(repr(self.character))
+          )
+      def __repr__(self):
+        params = []
+        self.repr_serialize(params)
+        return 'ast.PYACC.Text.Escape({0:s})'.format(', '.join(params))
+      # GENERATE END
+
+    class StackLocation(element.Element):
+      # GENERATE ELEMENT(int index) BEGIN
+      def __init__(
+        self,
+        tag = 'PYACC_Text_StackLocation',
+        attrib = {},
+        text = '',
+        children = [],
+        index = -1
+      ):
+        element.Element.__init__(
+          self,
+          tag,
+          attrib,
+          text,
+          children
+        )
+        self.index = (
+          element.deserialize_int(index)
+        if isinstance(index, str) else
+          index
+        )
+      def serialize(self, ref_list):
+        element.Element.serialize(self, ref_list)
+        self.set('index', element.serialize_int(self.index))
+      def deserialize(self, ref_list):
+        element.Element.deserialize(self, ref_list)
+        self.index = element.deserialize_int(self.get('index', '-1'))
+      def copy(self, factory = None):
+        result = element.Element.copy(
+          self,
+          StackLocation if factory is None else factory
+        )
+        result.index = self.index
+        return result
+      def repr_serialize(self, params):
+        element.Element.repr_serialize(self, params)
+        if self.index != -1:
+          params.append(
+            'index = {0:s}'.format(repr(self.index))
+          )
+      def __repr__(self):
+        params = []
+        self.repr_serialize(params)
+        return 'ast.PYACC.Text.StackLocation({0:s})'.format(', '.join(params))
+      # GENERATE END
+
+    class StackReference(element.Element):
+      # GENERATE ELEMENT(int index) BEGIN
+      def __init__(
+        self,
+        tag = 'PYACC_Text_StackReference',
+        attrib = {},
+        text = '',
+        children = [],
+        index = -1
+      ):
+        element.Element.__init__(
+          self,
+          tag,
+          attrib,
+          text,
+          children
+        )
+        self.index = (
+          element.deserialize_int(index)
+        if isinstance(index, str) else
+          index
+        )
+      def serialize(self, ref_list):
+        element.Element.serialize(self, ref_list)
+        self.set('index', element.serialize_int(self.index))
+      def deserialize(self, ref_list):
+        element.Element.deserialize(self, ref_list)
+        self.index = element.deserialize_int(self.get('index', '-1'))
+      def copy(self, factory = None):
+        result = element.Element.copy(
+          self,
+          StackReference if factory is None else factory
+        )
+        result.index = self.index
+        return result
+      def repr_serialize(self, params):
+        element.Element.repr_serialize(self, params)
+        if self.index != -1:
+          params.append(
+            'index = {0:s}'.format(repr(self.index))
+          )
+      def __repr__(self):
+        params = []
+        self.repr_serialize(params)
+        return 'ast.PYACC.Text.StackReference({0:s})'.format(', '.join(params))
+      # GENERATE END
+
+    class ValueLocation(element.Element):
+      # GENERATE ELEMENT() BEGIN
+      def __init__(
+        self,
+        tag = 'PYACC_Text_ValueLocation',
+        attrib = {},
+        text = '',
+        children = []
+      ):
+        element.Element.__init__(
+          self,
+          tag,
+          attrib,
+          text,
+          children
+        )
+      def copy(self, factory = None):
+        result = element.Element.copy(
+          self,
+          ValueLocation if factory is None else factory
+        )
+        return result
+      def __repr__(self):
+        params = []
+        self.repr_serialize(params)
+        return 'ast.PYACC.Text.ValueLocation({0:s})'.format(', '.join(params))
+      # GENERATE END
+
+    class ValueReference(element.Element):
+      # GENERATE ELEMENT() BEGIN
+      def __init__(
+        self,
+        tag = 'PYACC_Text_ValueReference',
+        attrib = {},
+        text = '',
+        children = []
+      ):
+        element.Element.__init__(
+          self,
+          tag,
+          attrib,
+          text,
+          children
+        )
+      def copy(self, factory = None):
+        result = element.Element.copy(
+          self,
+          ValueReference if factory is None else factory
+        )
+        return result
+      def __repr__(self):
+        params = []
+        self.repr_serialize(params)
+        return 'ast.PYACC.Text.ValueReference({0:s})'.format(', '.join(params))
+      # GENERATE END
+
     # GENERATE ELEMENT() BEGIN
     def __init__(
       self,
@@ -1330,6 +1293,80 @@ class PYACC(element.Element):
       self.repr_serialize(params)
       return 'ast.PYACC.Text({0:s})'.format(', '.join(params))
     # GENERATE END
+    def get_text(self, len_production = 0):
+      return ''.join(
+        [
+          j
+          for i in range(len(self))
+          for j in [
+            element.get_text(self, i),
+            (
+              '(yyvsp[{0:d}])'.format(self[i].index - len_production)
+            if isinstance(self[i], PYACC.Text.StackReference) else
+              '(yyval)'
+            if isinstance(self[i], PYACC.Text.ValueReference) else
+              chr(self[i].character)
+            )
+          ]
+        ] +
+        [element.get_text(self, len(self))]
+      )
+
+  class BracedCode(Text):
+    # GENERATE ELEMENT() BEGIN
+    def __init__(
+      self,
+      tag = 'PYACC_BracedCode',
+      attrib = {},
+      text = '',
+      children = []
+    ):
+      PYACC.Text.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+    def copy(self, factory = None):
+      result = PYACC.Text.copy(
+        self,
+        BracedCode if factory is None else factory
+      )
+      return result
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.PYACC.BracedCode({0:s})'.format(', '.join(params))
+    # GENERATE END
+
+  class ID(Text):
+    # GENERATE ELEMENT() BEGIN
+    def __init__(
+      self,
+      tag = 'PYACC_ID',
+      attrib = {},
+      text = '',
+      children = []
+    ):
+      PYACC.Text.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+    def copy(self, factory = None):
+      result = PYACC.Text.copy(
+        self,
+        ID if factory is None else factory
+      )
+      return result
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.PYACC.ID({0:s})'.format(', '.join(params))
+    # GENERATE END
 
   class Section1Or2(Section):
     class Code(Item):
@@ -2411,7 +2448,7 @@ class PYACC(element.Element):
       return 'ast.PYACC.Section2({0:s})'.format(', '.join(params))
     # GENERATE END
 
-  class Section3(Section):
+  class Section3(Text):
     # GENERATE ELEMENT() BEGIN
     def __init__(
       self,
@@ -2420,7 +2457,7 @@ class PYACC(element.Element):
       text = '',
       children = []
     ):
-      PYACC.Section.__init__(
+      PYACC.Text.__init__(
         self,
         tag,
         attrib,
@@ -2428,7 +2465,7 @@ class PYACC(element.Element):
         children
       )
     def copy(self, factory = None):
-      result = PYACC.Section.copy(
+      result = PYACC.Text.copy(
         self,
         Section3 if factory is None else factory
       )
@@ -2446,62 +2483,6 @@ class PYACC(element.Element):
     ):
       pass
 
-  class ValueLocation(element.Element):
-    # GENERATE ELEMENT() BEGIN
-    def __init__(
-      self,
-      tag = 'PYACC_ValueLocation',
-      attrib = {},
-      text = '',
-      children = []
-    ):
-      element.Element.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-    def copy(self, factory = None):
-      result = element.Element.copy(
-        self,
-        ValueLocation if factory is None else factory
-      )
-      return result
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.PYACC.ValueLocation({0:s})'.format(', '.join(params))
-    # GENERATE END
-
-  class ValueReference(element.Element):
-    # GENERATE ELEMENT() BEGIN
-    def __init__(
-      self,
-      tag = 'PYACC_ValueReference',
-      attrib = {},
-      text = '',
-      children = []
-    ):
-      element.Element.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-    def copy(self, factory = None):
-      result = element.Element.copy(
-        self,
-        ValueReference if factory is None else factory
-      )
-      return result
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.PYACC.ValueReference({0:s})'.format(', '.join(params))
-    # GENERATE END
-
   # GENERATE ELEMENT(list(ref) prologue_text, list(ref) terminals, list(ref) nonterminals, list(ref) productions, int first_nonterminal, int start_nonterminal, list(int) associativities) BEGIN
   def __init__(
     self,
@@ -2671,12 +2652,8 @@ class PYACC(element.Element):
     # perform the semantic analysis pass
     self.first_nonterminal = -1
     self.start_nonterminal = -1
-    for i in self:
-      i.post_process(
-        self,
-        character_to_symbol,
-        name_to_symbol
-      )
+    self[0].post_process(self, character_to_symbol, name_to_symbol)
+    self[1].post_process(self, character_to_symbol, name_to_symbol)
 
     # fill in token numbers that are not characters or overridden by user
     token = 0x100
@@ -2781,11 +2758,8 @@ tag_to_class = {
   'PYACC_Symbol': PYACC.Symbol,
   'PYACC_Terminal': PYACC.Terminal,
   'PYACC_Nonterminal': PYACC.Nonterminal,
-  'PYACC_BracedCode': PYACC.BracedCode,
   'PYACC_BracedPredicate': PYACC.BracedPredicate,
   'PYACC_Char': PYACC.Char,
-  'PYACC_Escape': PYACC.Escape,
-  'PYACC_ID': PYACC.ID,
   'PYACC_Int': PYACC.Int,
   'PYACC_Production': PYACC.Production,
   'PYACC_Production_Item': PYACC.Production.Item,
@@ -2796,14 +2770,19 @@ tag_to_class = {
   'PYACC_Production_Prec': PYACC.Production.Prec,
   'PYACC_Production_SymbolRef': PYACC.Production.SymbolRef,
   'PYACC_Section': PYACC.Section,
-  'PYACC_StackLocation': PYACC.StackLocation,
-  'PYACC_StackReference': PYACC.StackReference,
   'PYACC_String': PYACC.String,
   'PYACC_TagOrSymbolRef': PYACC.TagOrSymbolRef,
   'PYACC_Tag': PYACC.Tag,
   'PYACC_TerminalRef': PYACC.TerminalRef,
   'PYACC_NonterminalRef': PYACC.NonterminalRef,
   'PYACC_Text': PYACC.Text,
+  'PYACC_Text_Escape': PYACC.Text.Escape,
+  'PYACC_Text_StackLocation': PYACC.Text.StackLocation,
+  'PYACC_Text_StackReference': PYACC.Text.StackReference,
+  'PYACC_Text_ValueLocation': PYACC.Text.ValueLocation,
+  'PYACC_Text_ValueReference': PYACC.Text.ValueReference,
+  'PYACC_BracedCode': PYACC.BracedCode,
+  'PYACC_ID': PYACC.ID,
   'PYACC_Section1Or2': PYACC.Section1Or2,
   'PYACC_Section1Or2_Code': PYACC.Section1Or2.Code,
   'PYACC_Section1Or2_CodeProps': PYACC.Section1Or2.CodeProps,
@@ -2838,9 +2817,7 @@ tag_to_class = {
   'PYACC_Section1_YACC': PYACC.Section1.YACC,
   'PYACC_Section2': PYACC.Section2,
   'PYACC_Section2_Rules': PYACC.Section2.Rules,
-  'PYACC_Section3': PYACC.Section3,
-  'PYACC_ValueLocation': PYACC.ValueLocation,
-  'PYACC_ValueReference': PYACC.ValueReference
+  'PYACC_Section3': PYACC.Section3
 }
 def factory(tag, attrib = {}, *args, **kwargs):
   return tag_to_class.get(tag, element.Element)(tag, attrib, *args, **kwargs)
index a52c34e..23c39a6 100644 (file)
@@ -729,7 +729,7 @@ static const yytype_int16 yyr2[] =
             '''/* GENERATE SECTION3 BEGIN */
 {0:s}/*GENERATE SECTION3 END */
 '''.format(
-              '' if len(pyacc) < 3 else element.get_text(pyacc[2][0], 0)
+              '' if len(pyacc) < 3 else pyacc[2].get_text()
             )
           )
         else: