Normalize whitespace and indent in *.y.new, fix various conversion bugs
authorNick Downing <nick@ndcode.org>
Mon, 14 Jan 2019 07:09:28 +0000 (18:09 +1100)
committerNick Downing <nick@ndcode.org>
Mon, 14 Jan 2019 07:09:28 +0000 (18:09 +1100)
ast.py
scan_to_l.py
tests/parse.y
xml_to_y.py
y_to_python.py

diff --git a/ast.py b/ast.py
index 22bb2e1..fa3e58b 100644 (file)
--- a/ast.py
+++ b/ast.py
@@ -3607,8 +3607,10 @@ class AST(element.Element):
     def translate_declaration_or_statement(self, context):
       type, name = self[1].get_type_and_name(self[0].get_type())
       assert isinstance(type, AST.TypeFunction)
+      if len(context.lines):
+        context.lines.append('\n')
       context.lines.append(
-        '\n{0:s}def {1:s}({2:s}):\n'.format(
+        '{0:s}def {1:s}({2:s}):\n'.format(
           context.indent,
           name,
           ', '.join([i.name for i in type])
index be21b01..f35d0dc 100755 (executable)
@@ -2,9 +2,8 @@
 
 import element
 import sys
-import xml.etree.ElementTree
 
-root = xml.etree.ElementTree.parse(sys.stdin).getroot()
+root = element.deserialize(sys.stdin())
 
 def replace_in_action(i):
   if i.tag == 'AST_Section2_Rule_Action' and len(i):
index 8811acc..21e639b 100644 (file)
@@ -121,6 +121,10 @@ extern int piece0, piece1;
 int piece2, piece3;
 void piece_insert(int n, const void *str);
 
+#if 1 /* don't use the macros for C to python translation */
+static void insert_before(int n, const void *str);
+static void insert_after(int n, const void *str);
+#else
 #define insert_before(n, str) \
  do { \
   piece_insert(piece2 + (n) * 2, (str)); \
@@ -133,6 +137,7 @@ void piece_insert(int n, const void *str);
   ++piece0; \
   ++piece3; \
  } while (0)
+#endif
 
 %}
 
@@ -1337,3 +1342,17 @@ void yyerror( const char *msg )
        {
                (void)msg;
        }
+
+#if 1 /* don't use the macros for C to python translation */
+static void insert_before(int n, const void *str) {
+  piece_insert(piece2 + n * 2, str);
+  ++piece0;
+  ++piece3;
+}
+
+static void insert_after(int n, const void *str) {
+  piece_insert(piece2 + n * 2 + 1, str);
+  ++piece0;
+  ++piece3;
+}
+#endif
index 6cb6974..cff1c55 100755 (executable)
@@ -2,8 +2,7 @@
 
 import element
 import sys
-import xml.etree.ElementTree
 
 sys.stdout.write(
-  element.to_text(xml.etree.ElementTree.parse(sys.stdin).getroot())
+  element.to_text(element.deserialize(sys.stdin))
 )
index 6333847..4aa4454 100755 (executable)
@@ -46,50 +46,95 @@ context = ast.Context()
 
 actions = []
 with open('a.c', 'w') as fout:
-  def extract(i, indent):
+  def extract(i):
     if i.tag == 'AST_Section1_Prologue':
       node = i[0]
       assert node.tag == 'AST_Text'
-      indent += '  '
+      indent = '  '
       initial = True
+      # we won't put code on same line as %{, though it's legal as input
+      element.set_text(
+        i,
+        0,
+        '{0:s}\n'.format(element.get_text(i, 0).rstrip())
+      )
     elif i.tag == 'AST_Production_Action':
       node = i[0]
       assert node.tag == 'AST_Text'
+      indent = '    '
       initial = False
     elif i.tag == 'AST_Section3':
       node = i
+      indent = ''
       initial = True
     else:
-      child_indent = indent
       if i.tag == 'AST':
+        element.set_text(
+          i,
+          0,
+          element.get_text(i, 0).lstrip()
+        )
+        for j in range(1, len(i)):
+          element.set_text(
+            i,
+            j,
+            '\n\n{0:s}\n\n'.format(element.get_text(i, j).strip())
+          )
+        element.set_text(
+          i,
+          len(i),
+          element.get_text(i, len(i)).lstrip()
+        )
+      elif i.tag == 'AST_Section2':
+        element.set_text(
+          i,
+          0,
+          element.get_text(i, 0).lstrip()
+        )
+        for j in range(1, len(i)):
+          element.set_text(
+            i,
+            j,
+            '\n\n{0:s}'.format(element.get_text(i, j).lstrip())
+          )
+        element.set_text(
+          i,
+          len(i),
+          element.get_text(i, len(i)).lstrip()
+        )
+      elif i.tag == 'AST_Section2_Rules':
+        element.set_text(
+          i,
+          0,
+          element.get_text(i, 0).lstrip()
+        )
         for j in range(1, len(i) + 1):
-          element.set_text(i, j, element.get_text(i, j).rstrip() + '\n')
-      #elif (
-      #  i.tag == 'AST_Section2_Rule' or
-      #  i.tag == 'AST_Section2_Rule_FLexRule'
-      #):
-      #  element.set_text(i, 0, element.get_text(i, 0).lstrip('\t '))
-      #elif i.tag == 'AST_Section2_CompoundRule':
-      #  child_indent += '  '
-      #  element.set_text(
-      #    i,
-      #    0,
-      #    indent + element.get_text(i, 0).lstrip('\t ')
-      #  )
-      #  for j in range(1, len(i)):
-      #    element.set_text(
-      #      i,
-      #      j,
-      #      #element.get_text(i, j).rstrip('\t ') + child_indent
-      #      my_rstrip(element.get_text(i, j), child_indent)
-      #    )
-      #  element.set_text(
-      #    i,
-      #    len(i),
-      #    indent + element.get_text(i, len(i)).lstrip('\t ')
-      #  )
+          element.set_text(
+            i,
+            j,
+            '\n  {0:s}'.format(element.get_text(i, j).strip())
+          )
+      elif i.tag == 'AST_Production':
+        for j in range(len(i)):
+          element.set_text(
+            i,
+            j,
+            (
+              '\n    {0:s}'.format(element.get_text(i, j).lstrip())
+            if (
+              i[j].tag == 'AST_Production_Action' or
+              (j > 0 and i[j - 1].tag == 'AST_Production_Action')
+            ) else
+              ' {0:s}'.format(element.get_text(i, j).lstrip())
+            )
+          )
+        element.set_text(
+          i,
+          len(i),
+          element.get_text(i, len(i)).lstrip()
+        )
       for j in i:
-        extract(j, child_indent)
+        extract(j)
       return
     #assert len(node) == 0
     #text = element.get_text(node, 0)
@@ -122,7 +167,7 @@ with open('a.c', 'w') as fout:
     fout.write('@@@\n')
 
     actions.append((node, indent, initial))
-  extract(root, '')
+  extract(root)
 
 os.system('gcc -I tests/flex_h -E a.c >a.i')
 with open('a.i') as fin:
@@ -157,9 +202,9 @@ with open('a.i') as fin:
         context,
         'void a(void) {0:s}'.format(text) # already has braces and \n
       )
-      assert text[:len(indent) + 10] == '\n{0:s}def a():\n'.format(indent)
-      text = text[len(indent) + 10:]
-      text = '{{\n{0:s}{1:s}}}\n'.format(text, indent)
+      assert text[:len(indent) + 9] == '{0:s}def a():\n'.format(indent)
+      text = '{{\n{0:s}{1:s}}}'.format(text[len(indent) + 9:], indent)
+    del node[:]
     element.set_text(node, 0, text)
 
 xml.etree.ElementTree.ElementTree(root).write(