First cut at translating parse-gram.y from Bison, fix ANSI C switch statement
authorNick Downing <nick@ndcode.org>
Wed, 16 Jan 2019 05:35:56 +0000 (16:35 +1100)
committerNick Downing <nick@ndcode.org>
Wed, 16 Jan 2019 05:36:32 +0000 (16:36 +1100)
ansi_c.l
ast.py
o.sh
r.sh [new file with mode: 0755]
tests/parse-gram.y
y_to_python.py

index 54aaf60..55d36cd 100644 (file)
--- a/ansi_c.l
+++ b/ansi_c.l
@@ -80,14 +80,14 @@ import y_tab
 "_Thread_local"                                return y_tab.THREAD_LOCAL
 "__func__"                             return y_tab.FUNC_NAME
 
-"FILE"|"GRAM_STYPE"|"bool"|"boundary"|"code_props"|"location"|"named_ref"|"scanflags_t"|"size_t"|"symbol_list"|"uniqstr"|"variant"|"warnings" {
+"FILE"|"GRAM_STYPE"|"YYLTYPE"|"assoc"|"bool"|"boundary"|"code_props"|"code_props_type"|"location"|"muscle_kind"|"named_ref"|"param_type"|"scanflags_t"|"size_t"|"symbol"|"symbol_class"|"symbol_list"|"uniqstr"|"variant"|"warnings" {
   # THIS IS A HACK FOR NOW
   return y_tab.TYPEDEF_NAME
 }
 
  /* hack for yacc/bison specification */
 (?E{ast.AST.Identifier}{L}{A}*) |
-(?E{ast.AST.Identifier}"$$"|"$"{D}+) {
+(?E{ast.AST.Identifier}[$@]("$"|{D}+)) {
   return y_tab.IDENTIFIER
 }
 
diff --git a/ast.py b/ast.py
index c974fdf..62fb950 100644 (file)
--- a/ast.py
+++ b/ast.py
@@ -4542,25 +4542,46 @@ class AST(element.Element):
       if_text = 'if'
       for i in self[1][0]:
         if isinstance(i, AST.StatementCase):
+          cond_expr = AST.ExpressionEqual(
+            children = [
+              self[0],
+              i[0]
+            ],
+            binary_operator = ' == ',
+            precedence = 8
+          )
+          j = i[1]
+          while isinstance(j, AST.StatementCase):
+            cond_expr = AST.ExpressionLogicalOr(
+              children = [
+                cond_expr,
+                AST.ExpressionEqual(
+                  children = [
+                    self[0],
+                    j[0]
+                  ],
+                  binary_operator = ' == ',
+                  precedence = 8
+                )
+              ],
+              binary_operator = ' or ',
+              precedence = 3
+            )
+            j = j[1]
           context.lines.append(
             '{0:s}{1:s} {2:s}:\n'.format(
               indent_save,
               if_text,
-              AST.ExpressionEqual(
-                children = [
-                  self[0],
-                  i[0]
-                ],
-                binary_operator = ' == ',
-                precedence = 8
-              ).translate_expression(context, 0)
+              cond_expr.translate_expression(context, 0)
             )
           )
           if_text = 'elif'
+          j.translate_declaration_or_statement(context)
         elif isinstance(i, AST.StatementDefault):
           context.lines.append(
             '{0:s}else:\n'.format(indent_save)
           )
+          self[0].translate_declaration_or_statement(context)
         else:
           i.translate_declaration_or_statement(context)
       context.indent = indent_save
diff --git a/o.sh b/o.sh
index 5a85fe7..e0b0206 100755 (executable)
--- a/o.sh
+++ b/o.sh
@@ -1,4 +1,4 @@
 #!/bin/sh
 ../bootstrap_bison.git/src/bison -o /dev/null tests/parse.y 2>tests/parse.y.xml
-./y_to_python.py <tests/parse.y.xml >tests/parse.y.new.xml
+./y_to_python.py -I tests/flex_h <tests/parse.y.xml >tests/parse.y.new.xml
 ./xml_to_y.py <tests/parse.y.new.xml >tests/parse.y.new
diff --git a/r.sh b/r.sh
new file mode 100755 (executable)
index 0000000..550049a
--- /dev/null
+++ b/r.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+../bootstrap_bison.git/src/bison -o /dev/null tests/parse-gram.y 2>tests/parse-gram.y.xml
+./y_to_python.py -I tests/bison_h -I tests/bison_h/src <tests/parse-gram.y.xml >tests/parse-gram.y.new.xml
+./xml_to_y.py <tests/parse-gram.y.new.xml >tests/parse-gram.y.new
index b7f92fd..3e9a67a 100644 (file)
   int nested_rhs = 0;
 }
 
-%define api.prefix {gram_}
+/* Nick %define api.prefix {gram_} */
 %define api.pure full
 %define locations
 %define parse.error verbose
 %define parse.lac full
 %define parse.trace
-%defines
+/* Nick %defines */
 %expect 0
-%verbose
+/* Nick %verbose */
 
 %initial-action
 {
 %token <integer> INT "integer"
 %printer { fprintf (yyo, "%d", $$); } <integer>
 
-%union {symbol *symbol;}
+%union {symbol *symbolXXX;}
 %type <symbol> id id_colon string_as_id symbol symbol.prec
 %printer { fprintf (yyo, "%s", $$->tag); } <symbol>
 %printer { fprintf (yyo, "%s:", $$->tag); } id_colon
 
-%union {assoc assoc;};
+%union {assoc assocXXX;};
 %type <assoc> precedence_declarator
 
 %union {symbol_list *list;}
 %type <list>  symbols.1 symbols.prec generic_symlist generic_symlist_item
 
-%union {named_ref *named_ref;}
+%union {named_ref *named_refXXX;}
 %type <named_ref> named_ref.opt
 
 /*---------.
@@ -1055,7 +1055,7 @@ translate_code_braceless (char *code, location loc)
 static void
 add_param (param_type type, char *decl, location loc)
 {
-  static char const alphanum[26 + 26 + 1 + 10 + 1] =
+  static char const alphanum[64 /* Nick 26 + 26 + 1 + 10 + 1 */] =
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "_"
index 4aa4454..97e50bc 100755 (executable)
@@ -47,7 +47,7 @@ context = ast.Context()
 actions = []
 with open('a.c', 'w') as fout:
   def extract(i):
-    if i.tag == 'AST_Section1_Prologue':
+    if i.tag == 'AST_Section1_Prologue' or i.tag == 'AST_BracedCode':
       node = i[0]
       assert node.tag == 'AST_Text'
       indent = '  '
@@ -58,6 +58,11 @@ with open('a.c', 'w') as fout:
         0,
         '{0:s}\n'.format(element.get_text(i, 0).rstrip())
       )
+    elif i.tag == 'AST_Section1Or2_CodeProps':
+      node = i[0]
+      assert node.tag == 'AST_Text'
+      indent = ''
+      initial = False
     elif i.tag == 'AST_Production_Action':
       node = i[0]
       assert node.tag == 'AST_Text'
@@ -146,9 +151,10 @@ with open('a.c', 'w') as fout:
     while len(lines) and len(lines[0]) == 0:
       del lines[0]
     for line in lines:
+      temp = line.lstrip()
       if (
-        (line[:10] == '#include <' and line[-3:] == '.h>') or
-        (line[:10] == '#include "' and line[-3:] == '.h"')
+        (temp[:10] == '#include <' and temp[-3:] == '.h>') or
+        (temp[:10] == '#include "' and temp[-3:] == '.h"')
       ):
         fout.write(
           '''@@@ IMPORT({0:s})
@@ -158,8 +164,8 @@ with open('a.c', 'w') as fout:
 #undef false
 #undef true
 @@@ IMPORT END\n'''.format(
-            line[10:-3].replace('/', '.'),
-            line
+            temp[10:-3].replace('/', '.'),
+            temp
           )
         )
       else:
@@ -169,7 +175,11 @@ with open('a.c', 'w') as fout:
     actions.append((node, indent, initial))
   extract(root)
 
-os.system('gcc -I tests/flex_h -E a.c >a.i')
+os.system(
+  'gcc{0:s} -E a.c >a.i'.format(
+    ''.join([' "{0:s}"'.format(i) for i in sys.argv[1:]])
+  )
+)
 with open('a.i') as fin:
   for node, indent, initial in actions:
     lines = []