Introduce the PLex.Text.get_text() method, and rearrange class hierarchy a bit
authorNick Downing <downing.nick@gmail.com>
Sat, 21 Jul 2018 12:29:08 +0000 (22:29 +1000)
committerNick Downing <downing.nick@gmail.com>
Sat, 21 Jul 2018 12:29:08 +0000 (22:29 +1000)
ast.py
flex_dfa.py

diff --git a/ast.py b/ast.py
index b8a166f..110c9b5 100644 (file)
--- a/ast.py
+++ b/ast.py
@@ -111,39 +111,11 @@ class PLex(element.Element):
     # GENERATE END
 
   # syntax classes
-  class Name(element.Element):
-    # GENERATE ELEMENT() BEGIN
-    def __init__(
-      self,
-      tag = 'PLex_Name',
-      attrib = {},
-      text = '',
-      children = []
-    ):
-      element.Element.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-    def copy(self, factory = None):
-      result = element.Element.copy(
-        self,
-        Name if factory is None else factory
-      )
-      return result
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.PLex.Name({0:s})'.format(', '.join(params))
-    # GENERATE END
-
-  class Section(element.Element):
+  class Text(element.Element):
     # GENERATE ELEMENT() BEGIN
     def __init__(
       self,
-      tag = 'PLex_Section',
+      tag = 'PLex_Text',
       attrib = {},
       text = '',
       children = []
@@ -158,40 +130,27 @@ class PLex(element.Element):
     def copy(self, factory = None):
       result = element.Element.copy(
         self,
-        Section if factory is None else factory
+        Text if factory is None else factory
       )
       return result
     def __repr__(self):
       params = []
       self.repr_serialize(params)
-      return 'ast.PLex.Section({0:s})'.format(', '.join(params))
+      return 'ast.PLex.Text({0:s})'.format(', '.join(params))
     # GENERATE END
-    def post_process(
-      self,
-      plex,
-      name_to_start_condition,
-      all_start_conditions,
-      inclusive_start_conditions
-    ):
-      for i in self:
-        i.post_process(
-          plex,
-          self,
-          name_to_start_condition,
-          all_start_conditions,
-          inclusive_start_conditions
-        )
+    def get_text(self):
+      return element.get_text(self, 0)
 
-  class Text(element.Element):
+  class Name(Text):
     # GENERATE ELEMENT() BEGIN
     def __init__(
       self,
-      tag = 'PLex_Text',
+      tag = 'PLex_Name',
       attrib = {},
       text = '',
       children = []
     ):
-      element.Element.__init__(
+      PLex.Text.__init__(
         self,
         tag,
         attrib,
@@ -199,18 +158,18 @@ class PLex(element.Element):
         children
       )
     def copy(self, factory = None):
-      result = element.Element.copy(
+      result = PLex.Text.copy(
         self,
-        Text if factory is None else factory
+        Name if factory is None else factory
       )
       return result
     def __repr__(self):
       params = []
       self.repr_serialize(params)
-      return 'ast.PLex.Text({0:s})'.format(', '.join(params))
+      return 'ast.PLex.Name({0:s})'.format(', '.join(params))
     # GENERATE END
 
-  class Section1Or2(Section):
+  class Section1Or2(element.Element):
     class CodeBlock(Item):
       # GENERATE ELEMENT() BEGIN
       def __init__(
@@ -257,7 +216,7 @@ class PLex(element.Element):
       children = [],
       code_blocks_text = []
     ):
-      PLex.Section.__init__(
+      element.Element.__init__(
         self,
         tag,
         attrib,
@@ -266,26 +225,26 @@ class PLex(element.Element):
       )
       self.code_blocks_text = code_blocks_text
     def serialize(self, ref_list):
-      PLex.Section.serialize(self, ref_list)
+      element.Element.serialize(self, ref_list)
       self.set(
         'code_blocks_text',
         ' '.join([element.serialize_ref(i, ref_list) for i in self.code_blocks_text])
       )
     def deserialize(self, ref_list):
-      PLex.Section.deserialize(self, ref_list)
+      element.Element.deserialize(self, ref_list)
       self.code_blocks_text = [
         element.deserialize_ref(i, ref_list)
         for i in self.get('code_blocks_text', '').split()
       ]
     def copy(self, factory = None):
-      result = PLex.Section.copy(
+      result = element.Element.copy(
         self,
         Section1Or2 if factory is None else factory
       )
       result.code_blocks_text = self.code_blocks_text
       return result
     def repr_serialize(self, params):
-      PLex.Section.repr_serialize(self, params)
+      element.Element.repr_serialize(self, params)
       if len(self.code_blocks_text):
         params.append(
           'code_blocks_text = [{0:s}]'.format(
@@ -297,6 +256,21 @@ class PLex(element.Element):
       self.repr_serialize(params)
       return 'ast.PLex.Section1Or2({0:s})'.format(', '.join(params))
     # GENERATE END
+    def post_process(
+      self,
+      plex,
+      name_to_start_condition,
+      all_start_conditions,
+      inclusive_start_conditions
+    ):
+      for i in self:
+        i.post_process(
+          plex,
+          self,
+          name_to_start_condition,
+          all_start_conditions,
+          inclusive_start_conditions
+        )
 
   class Section1(Section1Or2):
     class Options(Item):
@@ -629,8 +603,7 @@ class PLex(element.Element):
         inclusive_start_conditions
       ):
         for i in self:
-          assert isinstance(i, PLex.Name)
-          name = element.get_text(i, 0)
+          name = i.get_text()
           assert name not in name_to_start_condition
           name_to_start_condition[name] = len(plex.start_conditions)
           all_start_conditions.add(len(plex.start_conditions))
@@ -756,7 +729,7 @@ class PLex(element.Element):
       self.reject = True
       self.yymore = True
       self.yywrap = True
-      PLex.Section.post_process(
+      PLex.Section1Or2.post_process(
         self,
         plex,
         name_to_start_condition,
@@ -942,9 +915,8 @@ class PLex(element.Element):
         else:
           start_condition_set = set()
           for i in start_conditions:
-            assert isinstance(i, PLex.Name)
             start_condition_set.add(
-              name_to_start_condition[element.get_text(i, 0)]
+              name_to_start_condition[i.get_text()]
             )
         expr = self[1]
         trailing_context = self[2]
@@ -1016,7 +988,7 @@ class PLex(element.Element):
       return 'ast.PLex.Section2({0:s})'.format(', '.join(params))
     # GENERATE END
 
-  class Section3(Section):
+  class Section3(Text):
     # GENERATE ELEMENT() BEGIN
     def __init__(
       self,
@@ -1025,7 +997,7 @@ class PLex(element.Element):
       text = '',
       children = []
     ):
-      PLex.Section.__init__(
+      PLex.Text.__init__(
         self,
         tag,
         attrib,
@@ -1033,7 +1005,7 @@ class PLex(element.Element):
         children
       )
     def copy(self, factory = None):
-      result = PLex.Section.copy(
+      result = PLex.Text.copy(
         self,
         Section3 if factory is None else factory
       )
@@ -1127,6 +1099,7 @@ class PLex(element.Element):
     self.repr_serialize(params)
     return 'ast.PLex({0:s})'.format(', '.join(params))
   # GENERATE END
+
   def post_process(self):
     # variables that will be serialized
     self.start_conditions = [
@@ -1139,7 +1112,7 @@ class PLex(element.Element):
     ]
     self.actions_text = []
     self.eof_actions_text = [
-      PLex.Section2.Rule.Action(text = '\t\t\t\tyyterminate();\n')
+      PLex.Text(text = '\t\t\t\tyyterminate();\n')
     ]
 
     # variables that won't be serialized
@@ -1147,13 +1120,19 @@ class PLex(element.Element):
     all_start_conditions = set([0])
     inclusive_start_conditions = set([0])
 
-    for i in self:
-      i.post_process(
-        self,
-        name_to_start_condition,
-        all_start_conditions,
-        inclusive_start_conditions
-      )
+    # perform the semantic analysis pass
+    self[0].post_process(
+      self,
+      name_to_start_condition,
+      all_start_conditions,
+      inclusive_start_conditions
+    )
+    self[1].post_process(
+      self,
+      name_to_start_condition,
+      all_start_conditions,
+      inclusive_start_conditions
+    )
 
     # add default rule to each expr, then make it greedy
     for i in range(len(self.start_conditions)):
@@ -1189,6 +1168,7 @@ class PLex(element.Element):
           ]
         )
     self.actions_text.append(PLex.Text(text = 'ECHO;\n'))
+
   def to_nfa(self):
     _nfa = nfa.NFA()
     for i in self.start_conditions:
@@ -1201,9 +1181,8 @@ tag_to_class = {
   'Item': Item,
   'PLex': PLex,
   'PLex_StartCondition': PLex.StartCondition,
-  'PLex_Name': PLex.Name,
-  'PLex_Section': PLex.Section,
   'PLex_Text': PLex.Text,
+  'PLex_Name': PLex.Name,
   'PLex_Section1Or2': PLex.Section1Or2,
   'PLex_Section1Or2_CodeBlock': PLex.Section1Or2.CodeBlock,
   'PLex_Section1': PLex.Section1,
index 4e62b7a..98ef6f7 100644 (file)
@@ -327,7 +327,7 @@ static const flex_int16_t yy_chk[] = {{{6:s}
             '''/* GENERATE SECTION1 BEGIN */
 {0:s}/* GENERATE SECTION1 END */
 '''.format(
-              ''.join([element.get_text(i, 0) for i in plex[0].code_blocks_text])
+              ''.join([i.get_text() for i in plex[0].code_blocks_text])
             )
           )
         elif line == '/* GENERATE STARTCONDDECL */\n':
@@ -351,7 +351,7 @@ static const flex_int16_t yy_chk[] = {{{6:s}
             '''/* GENERATE SECTION2INITIAL BEGIN */
 {0:s}/* GENERATE SECTION2INITIAL END */
 '''.format(
-              ''.join([element.get_text(i, 0) for i in plex[1].code_blocks_text])
+              ''.join([i.get_text() for i in plex[1].code_blocks_text])
             )
           )
         elif line == '/* GENERATE SECTION2 */\n':
@@ -375,7 +375,7 @@ YY_RULE_SETUP
 {1:s}  YY_BREAK
 '''.format(
                     i,
-                    element.get_text(plex.actions_text[i], 0)
+                    plex.actions_text[i].get_text()
                   )
                   for i in range(len(plex.actions_text))
                 ]
@@ -391,7 +391,7 @@ YY_RULE_SETUP
                         for j in eof_action_to_start_conditions[i]
                       ]
                     ),
-                    element.get_text(plex.eof_actions_text[i], 0)
+                    plex.eof_actions_text[i].get_text()
                   )
                   for i in range(len(plex.eof_actions_text))
                   if len(eof_action_to_start_conditions[i]) > 0
@@ -404,7 +404,7 @@ YY_RULE_SETUP
             '''/* GENERATE SECTION3 BEGIN */
 {0:s}/*GENERATE SECTION3 END */
 '''.format(
-              '' if len(plex) < 3 else element.get_text(plex[2], 0)
+              '' if len(plex) < 3 else plex[2].get_text()
             )
           )
         else: