Add type analysis system from ansi_c.py in regex.git with some slight updates
authorNick Downing <nick@ndcode.org>
Sat, 12 Jan 2019 23:04:51 +0000 (10:04 +1100)
committerNick Downing <nick@ndcode.org>
Sat, 12 Jan 2019 23:04:51 +0000 (10:04 +1100)
.gitignore
ansi_c.py
ast.py
n.sh

index 2d3c882..21fcc18 100644 (file)
@@ -2,6 +2,7 @@ __pycache__
 a.c
 a.i
 a.xml
+b.xml
 ansi_c.l.xml
 ansi_c.y.xml
 lex_yy.py
index bcf8f26..bda910b 100755 (executable)
--- a/ansi_c.py
+++ b/ansi_c.py
@@ -26,3 +26,10 @@ root = y_tab.yyparse(ast.AST.TranslationUnit)
 element.serialize(root, 'a.xml', 'utf-8')
 root = element.deserialize('a.xml', ast.factory, 'utf-8')
 xml.etree.ElementTree.dump(root)
+
+for i in root:
+  if isinstance(i, ast.AST.Declaration):
+    base_type = i[0].get_type()
+    for j in i[1]:
+      type, name = j[0].get_type_and_name(base_type)
+      sys.stdout.write('{0:s} {1:s}\n'.format(str(type), name))
diff --git a/ast.py b/ast.py
index 3e356bd..8acfc01 100644 (file)
--- a/ast.py
+++ b/ast.py
@@ -18,6 +18,7 @@ class Context:
     self.translate_identifier = translate_identifier
 
 class AST(element.Element):
+  # internal classes
   class Text(element.Element):
     # GENERATE ELEMENT() BEGIN
     def __init__(
@@ -142,6 +143,545 @@ class AST(element.Element):
         text = text[:-1]
       element.set_text(self, len(self), '{0:s}\n'.format(text))
 
+  class Statement(DeclarationOrStatement):
+    # GENERATE ELEMENT() BEGIN
+    def __init__(
+      self,
+      tag = 'AST_Statement',
+      attrib = {},
+      text = '',
+      children = []
+    ):
+      AST.DeclarationOrStatement.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+    def copy(self, factory = None):
+      result = AST.DeclarationOrStatement.copy(
+        self,
+        Statement if factory is None else factory
+      )
+      return result
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.Statement({0:s})'.format(', '.join(params))
+    # GENERATE END
+
+  class Declarator(Element):
+    # GENERATE ELEMENT() BEGIN
+    def __init__(
+      self,
+      tag = 'AST_Declarator',
+      attrib = {},
+      text = '',
+      children = []
+    ):
+      AST.Element.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+    def copy(self, factory = None):
+      result = AST.Element.copy(
+        self,
+        Declarator if factory is None else factory
+      )
+      return result
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.Declarator({0:s})'.format(', '.join(params))
+    # GENERATE END
+    def get_type_and_name(self, base_type):
+      raise NotImplementedError
+
+  class Expression(Element):
+    # GENERATE ELEMENT() BEGIN
+    def __init__(
+      self,
+      tag = 'AST_Expression',
+      attrib = {},
+      text = '',
+      children = []
+    ):
+      AST.Element.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+    def copy(self, factory = None):
+      result = AST.Element.copy(
+        self,
+        Expression if factory is None else factory
+      )
+      return result
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.Expression({0:s})'.format(', '.join(params))
+    # GENERATE END
+
+  # type analysis
+  class Type(element.Element):
+    # GENERATE ELEMENT() BEGIN
+    def __init__(
+      self,
+      tag = 'AST_Type',
+      attrib = {},
+      text = '',
+      children = []
+    ):
+      element.Element.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+    def copy(self, factory = None):
+      result = element.Element.copy(
+        self,
+        Type if factory is None else factory
+      )
+      return result
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.Type({0:s})'.format(', '.join(params))
+    # GENERATE END
+
+  class TypeVoid(Type):
+    # GENERATE ELEMENT() BEGIN
+    def __init__(
+      self,
+      tag = 'AST_TypeVoid',
+      attrib = {},
+      text = '',
+      children = []
+    ):
+      AST.Type.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+    def copy(self, factory = None):
+      result = AST.Type.copy(
+        self,
+        TypeVoid if factory is None else factory
+      )
+      return result
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.TypeVoid({0:s})'.format(', '.join(params))
+    # GENERATE END
+    def __str__(self):
+      return 'void'
+
+  class TypeInt(Type):
+    # GENERATE ELEMENT(bool signed, int bits) BEGIN
+    def __init__(
+      self,
+      tag = 'AST_TypeInt',
+      attrib = {},
+      text = '',
+      children = [],
+      signed = False,
+      bits = -1
+    ):
+      AST.Type.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+      self.signed = (
+        element.deserialize_bool(signed)
+      if isinstance(signed, str) else
+        signed
+      )
+      self.bits = (
+        element.deserialize_int(bits)
+      if isinstance(bits, str) else
+        bits
+      )
+    def serialize(self, ref_list):
+      AST.Type.serialize(self, ref_list)
+      self.set('signed', element.serialize_bool(self.signed))
+      self.set('bits', element.serialize_int(self.bits))
+    def deserialize(self, ref_list):
+      AST.Type.deserialize(self, ref_list)
+      self.signed = element.deserialize_bool(self.get('signed', 'false'))
+      self.bits = element.deserialize_int(self.get('bits', '-1'))
+    def copy(self, factory = None):
+      result = AST.Type.copy(
+        self,
+        TypeInt if factory is None else factory
+      )
+      result.signed = self.signed
+      result.bits = self.bits
+      return result
+    def repr_serialize(self, params):
+      AST.Type.repr_serialize(self, params)
+      if self.signed != False:
+        params.append(
+          'signed = {0:s}'.format(repr(self.signed))
+        )
+      if self.bits != -1:
+        params.append(
+          'bits = {0:s}'.format(repr(self.bits))
+        )
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.TypeInt({0:s})'.format(', '.join(params))
+    # GENERATE END
+    def __str__(self):
+      return '{0:s}int{1:d}'.format(['u', ''][int(self.signed)], self.bits)
+
+  class TypeFloat(Type):
+    # GENERATE ELEMENT(int complex, int bits) BEGIN
+    def __init__(
+      self,
+      tag = 'AST_TypeFloat',
+      attrib = {},
+      text = '',
+      children = [],
+      complex = -1,
+      bits = -1
+    ):
+      AST.Type.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+      self.complex = (
+        element.deserialize_int(complex)
+      if isinstance(complex, str) else
+        complex
+      )
+      self.bits = (
+        element.deserialize_int(bits)
+      if isinstance(bits, str) else
+        bits
+      )
+    def serialize(self, ref_list):
+      AST.Type.serialize(self, ref_list)
+      self.set('complex', element.serialize_int(self.complex))
+      self.set('bits', element.serialize_int(self.bits))
+    def deserialize(self, ref_list):
+      AST.Type.deserialize(self, ref_list)
+      self.complex = element.deserialize_int(self.get('complex', '-1'))
+      self.bits = element.deserialize_int(self.get('bits', '-1'))
+    def copy(self, factory = None):
+      result = AST.Type.copy(
+        self,
+        TypeFloat if factory is None else factory
+      )
+      result.complex = self.complex
+      result.bits = self.bits
+      return result
+    def repr_serialize(self, params):
+      AST.Type.repr_serialize(self, params)
+      if self.complex != -1:
+        params.append(
+          'complex = {0:s}'.format(repr(self.complex))
+        )
+      if self.bits != -1:
+        params.append(
+          'bits = {0:s}'.format(repr(self.bits))
+        )
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.TypeFloat({0:s})'.format(', '.join(params))
+    # GENERATE END
+    def __str__(self):
+      return '{0:s}float{0:d}'.format(
+        ['', 'i', 'c'][int(self.complex)],
+        self.bits
+      )
+
+  class TypeBool(Type):
+    # GENERATE ELEMENT() BEGIN
+    def __init__(
+      self,
+      tag = 'AST_TypeBool',
+      attrib = {},
+      text = '',
+      children = []
+    ):
+      AST.Type.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+    def copy(self, factory = None):
+      result = AST.Type.copy(
+        self,
+        TypeBool if factory is None else factory
+      )
+      return result
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.TypeBool({0:s})'.format(', '.join(params))
+    # GENERATE END
+    def __str__(self):
+      return 'bool'
+
+  class TypePointer(Type):
+    # GENERATE ELEMENT(ref target_type) BEGIN
+    def __init__(
+      self,
+      tag = 'AST_TypePointer',
+      attrib = {},
+      text = '',
+      children = [],
+      target_type = None
+    ):
+      AST.Type.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+      self.target_type = target_type
+    def serialize(self, ref_list):
+      AST.Type.serialize(self, ref_list)
+      self.set('target_type', element.serialize_ref(self.target_type, ref_list))
+    def deserialize(self, ref_list):
+      AST.Type.deserialize(self, ref_list)
+      self.target_type = element.deserialize_ref(self.get('target_type', '-1'), ref_list)
+    def copy(self, factory = None):
+      result = AST.Type.copy(
+        self,
+        TypePointer if factory is None else factory
+      )
+      result.target_type = self.target_type
+      return result
+    def repr_serialize(self, params):
+      AST.Type.repr_serialize(self, params)
+      if self.target_type != None:
+        params.append(
+          'target_type = {0:s}'.format(repr(self.target_type))
+        )
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.TypePointer({0:s})'.format(', '.join(params))
+    # GENERATE END
+    def __str__(self):
+      return 'pointer<{0:s}>'.format(str(self.target_type))
+
+  class TypeArray(Type):
+    # GENERATE ELEMENT(ref element_type, int element_count) BEGIN
+    def __init__(
+      self,
+      tag = 'AST_TypeArray',
+      attrib = {},
+      text = '',
+      children = [],
+      element_type = None,
+      element_count = -1
+    ):
+      AST.Type.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+      self.element_type = element_type
+      self.element_count = (
+        element.deserialize_int(element_count)
+      if isinstance(element_count, str) else
+        element_count
+      )
+    def serialize(self, ref_list):
+      AST.Type.serialize(self, ref_list)
+      self.set('element_type', element.serialize_ref(self.element_type, ref_list))
+      self.set('element_count', element.serialize_int(self.element_count))
+    def deserialize(self, ref_list):
+      AST.Type.deserialize(self, ref_list)
+      self.element_type = element.deserialize_ref(self.get('element_type', '-1'), ref_list)
+      self.element_count = element.deserialize_int(self.get('element_count', '-1'))
+    def copy(self, factory = None):
+      result = AST.Type.copy(
+        self,
+        TypeArray if factory is None else factory
+      )
+      result.element_type = self.element_type
+      result.element_count = self.element_count
+      return result
+    def repr_serialize(self, params):
+      AST.Type.repr_serialize(self, params)
+      if self.element_type != None:
+        params.append(
+          'element_type = {0:s}'.format(repr(self.element_type))
+        )
+      if self.element_count != -1:
+        params.append(
+          'element_count = {0:s}'.format(repr(self.element_count))
+        )
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.TypeArray({0:s})'.format(', '.join(params))
+    # GENERATE END
+    def __str__(self):
+      return 'array<{0:s}: {1:s}>'.format(
+        str(self.element_type),
+        (
+          'UNSPECIFIED'
+        if self.element_count == -1 else
+          'C99_FLEXIBLE'
+        if self.element_count == -2 else
+          str(self.element_count)
+        )
+      )
+
+  class TypeFunction(Type):
+    class Argument(element.Element):
+      # GENERATE ELEMENT(ref type, str name) BEGIN
+      def __init__(
+        self,
+        tag = 'AST_TypeFunction_Argument',
+        attrib = {},
+        text = '',
+        children = [],
+        type = None,
+        name = ''
+      ):
+        element.Element.__init__(
+          self,
+          tag,
+          attrib,
+          text,
+          children
+        )
+        self.type = type
+        self.name = name
+      def serialize(self, ref_list):
+        element.Element.serialize(self, ref_list)
+        self.set('type', element.serialize_ref(self.type, ref_list))
+        self.set('name', element.serialize_str(self.name))
+      def deserialize(self, ref_list):
+        element.Element.deserialize(self, ref_list)
+        self.type = element.deserialize_ref(self.get('type', '-1'), ref_list)
+        self.name = element.deserialize_str(self.get('name', ''))
+      def copy(self, factory = None):
+        result = element.Element.copy(
+          self,
+          Argument if factory is None else factory
+        )
+        result.type = self.type
+        result.name = self.name
+        return result
+      def repr_serialize(self, params):
+        element.Element.repr_serialize(self, params)
+        if self.type != None:
+          params.append(
+            'type = {0:s}'.format(repr(self.type))
+          )
+        if self.name != '':
+          params.append(
+            'name = {0:s}'.format(repr(self.name))
+          )
+      def __repr__(self):
+        params = []
+        self.repr_serialize(params)
+        return 'ast.AST.TypeFunction.Argument({0:s})'.format(', '.join(params))
+      # GENERATE END
+      def __str__(self):
+        return '{0:s} {1:s}'.format(
+          str(self.type),
+          'ABSTRACT' if self.name == '' else self.name
+        )
+
+    # GENERATE ELEMENT(ref return_type, bool is_varargs) BEGIN
+    def __init__(
+      self,
+      tag = 'AST_TypeFunction',
+      attrib = {},
+      text = '',
+      children = [],
+      return_type = None,
+      is_varargs = False
+    ):
+      AST.Type.__init__(
+        self,
+        tag,
+        attrib,
+        text,
+        children
+      )
+      self.return_type = return_type
+      self.is_varargs = (
+        element.deserialize_bool(is_varargs)
+      if isinstance(is_varargs, str) else
+        is_varargs
+      )
+    def serialize(self, ref_list):
+      AST.Type.serialize(self, ref_list)
+      self.set('return_type', element.serialize_ref(self.return_type, ref_list))
+      self.set('is_varargs', element.serialize_bool(self.is_varargs))
+    def deserialize(self, ref_list):
+      AST.Type.deserialize(self, ref_list)
+      self.return_type = element.deserialize_ref(self.get('return_type', '-1'), ref_list)
+      self.is_varargs = element.deserialize_bool(self.get('is_varargs', 'false'))
+    def copy(self, factory = None):
+      result = AST.Type.copy(
+        self,
+        TypeFunction if factory is None else factory
+      )
+      result.return_type = self.return_type
+      result.is_varargs = self.is_varargs
+      return result
+    def repr_serialize(self, params):
+      AST.Type.repr_serialize(self, params)
+      if self.return_type != None:
+        params.append(
+          'return_type = {0:s}'.format(repr(self.return_type))
+        )
+      if self.is_varargs != False:
+        params.append(
+          'is_varargs = {0:s}'.format(repr(self.is_varargs))
+        )
+    def __repr__(self):
+      params = []
+      self.repr_serialize(params)
+      return 'ast.AST.TypeFunction({0:s})'.format(', '.join(params))
+    # GENERATE END
+    def __str__(self):
+      return 'function<{0:s}: {1:s}>'.format(
+        str(self.return_type),
+        (
+          'void'
+        if len(self) == 0 else
+          ', '.join(
+            [str(i) for i in self] + (['...'] if self.is_varargs else [])
+          )
+        )
+      )
+
+  # syntax classes
   class AlignAsExpression(Element):
     # GENERATE ELEMENT() BEGIN
     def __init__(
@@ -382,7 +922,7 @@ class AST(element.Element):
       return 'ast.AST.DeclarationList({0:s})'.format(', '.join(params))
     # GENERATE END
 
-  class DeclarationSpecifierList(Element):
+  class DeclarationSpecifierList(element.Element):
     # GENERATE ELEMENT() BEGIN
     def __init__(
       self,
@@ -391,7 +931,7 @@ class AST(element.Element):
       text = '',
       children = []
     ):
-      AST.Element.__init__(
+      element.Element.__init__(
         self,
         tag,
         attrib,
@@ -399,7 +939,7 @@ class AST(element.Element):
         children
       )
     def copy(self, factory = None):
-      result = AST.Element.copy(
+      result = element.Element.copy(
         self,
         DeclarationSpecifierList if factory is None else factory
       )
@@ -409,34 +949,12 @@ class AST(element.Element):
       self.repr_serialize(params)
       return 'ast.AST.DeclarationSpecifierList({0:s})'.format(', '.join(params))
     # GENERATE END
-
-  class Declarator(Element):
-    # GENERATE ELEMENT() BEGIN
-    def __init__(
-      self,
-      tag = 'AST_Declarator',
-      attrib = {},
-      text = '',
-      children = []
-    ):
-      AST.Element.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-    def copy(self, factory = None):
-      result = AST.Element.copy(
-        self,
-        Declarator if factory is None else factory
-      )
-      return result
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.AST.Declarator({0:s})'.format(', '.join(params))
-    # GENERATE END
+    def get_type(self):
+      type_specifiers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+      for i in self:
+        if isinstance(i, AST.TypeSpecifier):
+          type_specifiers[i.n] += 1
+      return type_specifiers_to_type[tuple(type_specifiers)]
 
   class DeclaratorAbstract(Declarator):
     # GENERATE ELEMENT() BEGIN
@@ -447,7 +965,7 @@ class AST(element.Element):
       text = '',
       children = []
     ):
-      AST.Declarator.__init__(
+      element.Element.__init__(
         self,
         tag,
         attrib,
@@ -455,7 +973,7 @@ class AST(element.Element):
         children
       )
     def copy(self, factory = None):
-      result = AST.Declarator.copy(
+      result = element.Element.copy(
         self,
         DeclaratorAbstract if factory is None else factory
       )
@@ -465,6 +983,8 @@ class AST(element.Element):
       self.repr_serialize(params)
       return 'ast.AST.DeclaratorAbstract({0:s})'.format(', '.join(params))
     # GENERATE END
+    def get_type_and_name(self, base_type):
+      return base_type, ''
 
   class DeclaratorArray(Declarator):
     # GENERATE ELEMENT() BEGIN
@@ -475,7 +995,7 @@ class AST(element.Element):
       text = '',
       children = []
     ):
-      AST.Declarator.__init__(
+      element.Element.__init__(
         self,
         tag,
         attrib,
@@ -483,7 +1003,7 @@ class AST(element.Element):
         children
       )
     def copy(self, factory = None):
-      result = AST.Declarator.copy(
+      result = element.Element.copy(
         self,
         DeclaratorArray if factory is None else factory
       )
@@ -493,19 +1013,16 @@ class AST(element.Element):
       self.repr_serialize(params)
       return 'ast.AST.DeclaratorArray({0:s})'.format(', '.join(params))
     # GENERATE END
-    def translate(self, context):
-      assert len(self) == 3
-      self[0].translate(context)
-      self[1].translate(context)
-      self[2].translate(context)
-      element.set_text(self, 0, '')
-      element.set_text(self, 1, '[')
-      element.set_text(
-        self,
-        2,
-        ' ' if len(self[1]) or len(element.get_text(self[1], 0)) else ''
+    def get_type_and_name(self, base_type):
+      return self[0].get_type_and_name(
+        AST.TypeArray(
+          element_type = base_type,
+          element_count = int(
+            element.get_text(self[2], 0),
+            8 if element.get_text(self[2], 0)[:2] in octal_prefix else 0
+          )
+        )
       )
-      element.set_text(self, 3, ']')
 
   class DeclaratorEmpty(Declarator):
     # GENERATE ELEMENT() BEGIN
@@ -544,7 +1061,7 @@ class AST(element.Element):
       text = '',
       children = []
     ):
-      AST.Declarator.__init__(
+      element.Element.__init__(
         self,
         tag,
         attrib,
@@ -552,7 +1069,7 @@ class AST(element.Element):
         children
       )
     def copy(self, factory = None):
-      result = AST.Declarator.copy(
+      result = element.Element.copy(
         self,
         DeclaratorFunction if factory is None else factory
       )
@@ -562,26 +1079,17 @@ class AST(element.Element):
       self.repr_serialize(params)
       return 'ast.AST.DeclaratorFunction({0:s})'.format(', '.join(params))
     # GENERATE END
-    def translate(self, context):
-      assert len(self) == 3
-      self[0].translate(context)
-      self[1].translate(context)
-      assert isinstance(self[1], AST.ParameterDeclarationList)
-      if len(self[1]) == 1:
-        assert isinstance(self[1][0], AST.ParameterDeclaration)
-        assert isinstance(self[1][0][0], AST.DeclarationSpecifierList)
-        if (
-          len(self[1][0][0]) == 1 and
-          isinstance(self[1][0][0][0], AST.TypeSpecifier) and
-          self[1][0][0][0].n == 0 and
-          isinstance(self[1][0][1], AST.DeclaratorAbstract)
-        ):
-          del self[1][:]
-      self[2].translate(context)
-      element.set_text(self, 0, '')
-      element.set_text(self, 1, '(')
-      element.set_text(self, 2, '')
-      element.set_text(self, 3, ')')
+    def get_type_and_name(self, base_type):
+      func_type = TypeFunction(
+        return_type = base_type,
+        is_varargs = self[2].is_varargs,
+      )
+      for parameter_declaration in self[1]:
+        type, name = parameter_declaration[1].get_type_and_name(
+          parameter_declaration[0].get_type()
+        )
+        func_type.append(TypeFunction.Argument(type = type, name = name))
+      return self[0].get_type_and_name(func_type)
 
   class DeclaratorFunctionOldStyle(Declarator):
     # GENERATE ELEMENT() BEGIN
@@ -610,13 +1118,6 @@ class AST(element.Element):
       self.repr_serialize(params)
       return 'ast.AST.DeclaratorFunctionOldStyle({0:s})'.format(', '.join(params))
     # GENERATE END
-    def translate(self, context):
-      assert len(self) == 2
-      self[0].translate(context)
-      self[1].translate(context)
-      element.set_text(self, 0, '')
-      element.set_text(self, 1, '(')
-      element.set_text(self, 2, ')')
 
   class DeclaratorIdentifier(Declarator):
     # GENERATE ELEMENT() BEGIN
@@ -645,6 +1146,8 @@ class AST(element.Element):
       self.repr_serialize(params)
       return 'ast.AST.DeclaratorIdentifier({0:s})'.format(', '.join(params))
     # GENERATE END
+    def get_type_and_name(self, base_type):
+      return base_type, element.get_text(self[0], 0)
 
   class DeclaratorPointer(Declarator):
     # GENERATE ELEMENT() BEGIN
@@ -655,7 +1158,7 @@ class AST(element.Element):
       text = '',
       children = []
     ):
-      AST.Declarator.__init__(
+      element.Element.__init__(
         self,
         tag,
         attrib,
@@ -663,7 +1166,7 @@ class AST(element.Element):
         children
       )
     def copy(self, factory = None):
-      result = AST.Declarator.copy(
+      result = element.Element.copy(
         self,
         DeclaratorPointer if factory is None else factory
       )
@@ -673,15 +1176,9 @@ class AST(element.Element):
       self.repr_serialize(params)
       return 'ast.AST.DeclaratorPointer({0:s})'.format(', '.join(params))
     # GENERATE END
-    def translate(self, context):
-      assert len(self) == 2
-      self[0].translate(context)
-      self[1].translate(context)
-      element.set_text(self, 0, '*')
-      element.set_text(
-        self,
-        1,
-        ' ' if len(self[0]) or len(element.get_text(self[0], 0)) else ''
+    def get_type_and_name(self, base_type):
+      return self[1].get_type_and_name(
+        AST.TypePointer(target_type = base_type)
       )
 
   class DefaultTypeName(Element):
@@ -964,34 +1461,6 @@ class AST(element.Element):
       return 'ast.AST.EqualsInitializerEmpty({0:s})'.format(', '.join(params))
     # GENERATE END
 
-  class Expression(Element):
-    # GENERATE ELEMENT() BEGIN
-    def __init__(
-      self,
-      tag = 'AST_Expression',
-      attrib = {},
-      text = '',
-      children = []
-    ):
-      AST.Element.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-    def copy(self, factory = None):
-      result = AST.Element.copy(
-        self,
-        Expression if factory is None else factory
-      )
-      return result
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.AST.Expression({0:s})'.format(', '.join(params))
-    # GENERATE END
-
   class ExpressionAdd(Expression):
     # GENERATE ELEMENT() BEGIN
     def __init__(
@@ -3127,34 +3596,6 @@ class AST(element.Element):
       return 'ast.AST.SpecifierQualifierList({0:s})'.format(', '.join(params))
     # GENERATE END
 
-  class Statement(DeclarationOrStatement):
-    # GENERATE ELEMENT() BEGIN
-    def __init__(
-      self,
-      tag = 'AST_Statement',
-      attrib = {},
-      text = '',
-      children = []
-    ):
-      AST.DeclarationOrStatement.__init__(
-        self,
-        tag,
-        attrib,
-        text,
-        children
-      )
-    def copy(self, factory = None):
-      result = AST.DeclarationOrStatement.copy(
-        self,
-        Statement if factory is None else factory
-      )
-      return result
-    def __repr__(self):
-      params = []
-      self.repr_serialize(params)
-      return 'ast.AST.Statement({0:s})'.format(', '.join(params))
-    # GENERATE END
-
   class StatementBlock(Statement):
     # GENERATE ELEMENT() BEGIN
     def __init__(
@@ -4151,12 +4592,55 @@ class AST(element.Element):
     return 'ast.AST({0:s})'.format(', '.join(params))
   # GENERATE END
 
+type_specifiers_to_type = {
+  (1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): AST.TypeVoid(),
+  (0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 8),
+  (0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 8),
+  (0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 8),
+  (0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 16),
+  (0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 16),
+  (0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 16),
+  (0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
+  (0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
+  (0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 32),
+  (0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
+  (0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
+  (0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
+  (0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 32),
+  (0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 32),
+  (0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 64),
+  (0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 64),
+  (0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 64),
+  (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0): AST.TypeFloat(complex = 0, bits = 32),
+  (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0): AST.TypeFloat(complex = 2, bits = 32),
+  (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1): AST.TypeFloat(complex = 1, bits = 32),
+  (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0): AST.TypeFloat(complex = 0, bits = 64),
+  (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0): AST.TypeFloat(complex = 1, bits = 64),
+  (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1): AST.TypeFloat(complex = 2, bits = 64),
+  (0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0): AST.TypeBool()
+} 
+octal_prefix = set(
+  ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09']
+)
+
 # GENERATE FACTORY(element.Element) BEGIN
 tag_to_class = {
   'AST': AST,
   'AST_Text': AST.Text,
   'AST_Element': AST.Element,
   'AST_DeclarationOrStatement': AST.DeclarationOrStatement,
+  'AST_Statement': AST.Statement,
+  'AST_Declarator': AST.Declarator,
+  'AST_Expression': AST.Expression,
+  'AST_Type': AST.Type,
+  'AST_TypeVoid': AST.TypeVoid,
+  'AST_TypeInt': AST.TypeInt,
+  'AST_TypeFloat': AST.TypeFloat,
+  'AST_TypeBool': AST.TypeBool,
+  'AST_TypePointer': AST.TypePointer,
+  'AST_TypeArray': AST.TypeArray,
+  'AST_TypeFunction': AST.TypeFunction,
+  'AST_TypeFunction_Argument': AST.TypeFunction.Argument,
   'AST_AlignAsExpression': AST.AlignAsExpression,
   'AST_AlignAsType': AST.AlignAsType,
   'AST_ArgumentExpressionList': AST.ArgumentExpressionList,
@@ -4166,7 +4650,6 @@ tag_to_class = {
   'AST_Declaration': AST.Declaration,
   'AST_DeclarationList': AST.DeclarationList,
   'AST_DeclarationSpecifierList': AST.DeclarationSpecifierList,
-  'AST_Declarator': AST.Declarator,
   'AST_DeclaratorAbstract': AST.DeclaratorAbstract,
   'AST_DeclaratorArray': AST.DeclaratorArray,
   'AST_DeclaratorEmpty': AST.DeclaratorEmpty,
@@ -4184,7 +4667,6 @@ tag_to_class = {
   'AST_Enumerator': AST.Enumerator,
   'AST_EnumeratorList': AST.EnumeratorList,
   'AST_EqualsInitializerEmpty': AST.EqualsInitializerEmpty,
-  'AST_Expression': AST.Expression,
   'AST_ExpressionAdd': AST.ExpressionAdd,
   'AST_ExpressionAddAssignment': AST.ExpressionAddAssignment,
   'AST_ExpressionAddressOf': AST.ExpressionAddressOf,
@@ -4256,7 +4738,6 @@ tag_to_class = {
   'AST_ParameterDeclaration': AST.ParameterDeclaration,
   'AST_ParameterDeclarationList': AST.ParameterDeclarationList,
   'AST_SpecifierQualifierList': AST.SpecifierQualifierList,
-  'AST_Statement': AST.Statement,
   'AST_StatementBlock': AST.StatementBlock,
   'AST_StatementBreak': AST.StatementBreak,
   'AST_StatementCase': AST.StatementCase,
diff --git a/n.sh b/n.sh
index 7f3024d..f09b0d1 100755 (executable)
--- a/n.sh
+++ b/n.sh
@@ -1,4 +1,4 @@
 #!/bin/sh
-../bootstrap_flex.git/src/flex tests/scan.l 2>tests/scan.l.xml
+../bootstrap_flex.git/src/flex -o /dev/null tests/scan.l 2>tests/scan.l.xml
 ./l_to_python.py <tests/scan.l.xml >tests/scan.l.new.xml
 ./scan_to_l.py <tests/scan.l.new.xml >tests/scan.l.new