* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
+%{
+ import element
+ import sys
+%}
+
%%
class AST {
int precedence = -1;
bool right_to_left = False;
};
+ class Specifier;
/* type analysis */
class Type;
class TypeVoid: Type;
ref return_type = None;
bool varargs = False;
};
+ class TypeStructOrUnion: Type {
+ class Member {
+ ref type = None;
+ str name = '';
+ };
+ str name = '';
+ };
+ class TypeStruct: TypeStructOrUnion;
+ class TypeUnion: TypeStructOrUnion;
/* syntax classes */
class AlignAsExpression;
class AlignAsType;
class DesignatorInitializerList: InitializerOrExpression;
class DesignatorListEqualsEmpty;
class DesignatorList;
- class EnumSpecifier;
+ class EnumSpecifier: Specifier;
class Enumerator;
class EnumeratorList;
class EqualsInitializerEmpty;
class ExpressionSubtract: ExpressionBinary;
class ExpressionSubtractAssignment: ExpressionBinary;
class FunctionDefinition: DeclarationOrStatement;
- class FunctionSpecifier {
+ class FunctionSpecifier: Specifier {
int n = -1;
};
class GenericAssociation;
class StatementSwitch: Statement;
class StatementWhile: Statement;
class StaticAssertDeclaration: DeclarationOrStatement;
- class StorageClassSpecifier {
+ class StorageClassSpecifier: Specifier {
int n = -1;
};
class StructDeclaration;
class StructDeclarationList;
class StructDeclarator;
class StructDeclaratorList;
- class StructSpecifier;
+ class StructSpecifier: Specifier;
class TypeName;
class TypeQualifier {
int n = -1;
};
class TypeQualifierList;
class TypeQualifierOrStaticList;
- class TypeSpecifier {
+ class TypeSpecifier: Specifier {
int n = -1;
};
- class UnionSpecifier;
+ class UnionSpecifier: Specifier;
class TranslationUnit;
};
%%
+def snake_to_camel(text):
+ return ''.join([i[0].upper() + i[1:] for i in text.split('_')])
+
class Context:
def __init__(
self,
indent = '',
lines = [],
top_level = True,
+ enclosing_struct = None,
enclosing_loop = None,
translate_identifier = {
'NULL': 'None',
self.indent = indent
self.lines = lines
self.top_level = top_level
+ self.enclosing_struct = enclosing_struct
self.enclosing_loop = enclosing_loop
self.translate_identifier = translate_identifier
)
def factory(tag, *args, **kwargs):
- return tag_to_class.get(tag, element.Element)(tag, *args, **kwargs)
+ return tag_to_class[tag](*args, **kwargs)
@method(AST.DeclarationOrStatement)
def translate_declaration_or_statement(self, context):
@method(AST.Declaration)
def translate_declaration_or_statement(self, context):
base_type = self.children[0].get_type()
+ if isinstance(base_type, AST.TypeStructOrUnion) and len(base_type.children):
+ context.lines.append(
+ '''{0:s}class {1:s}:
+{2:s} def __init__(
+{3:s} self{4:s}
+{5:s} ):{6:s}
+'''.format(
+ context.indent,
+ snake_to_camel(base_type.name),
+ context.indent,
+ context.indent,
+ ''.join(
+ [
+ ',\n{0:s} {1:s} = {2:s}'.format(
+ context.indent,
+ i.name,
+ i.type.translate_zero(context)
+ )
+ for i in base_type.children
+ ]
+ ),
+ context.indent,
+ ''.join(
+ [
+ '\n{0:s} self.{1:s} = {2:s}'.format(
+ context.indent,
+ i.name,
+ i.name
+ )
+ for i in base_type.children
+ ]
+ )
+ )
+ )
for i in self.children[1].children:
type, name = i.children[0].get_type_and_name(base_type)
if not isinstance(type, AST.TypeFunction):
[self.element_type.translate_zero(context)] * self.element_count
)
)
+@method(AST.TypeStructOrUnion)
+def translate_zero(self, context):
+ return '{0:s}()'.format(snake_to_camel(self.name))
del translate_zero
@method(AST.TypeVoid)
i.translate_declaration_or_statement(context)
del translate_block_item_list
+@method(AST.StructDeclaration)
+def struct_get_members(self, children):
+ base_type = self.children[0].get_type()
+ for i in self.children[1].children:
+ type, name = i.get_type_and_name(base_type)
+ children.append(AST.TypeStructOrUnion.Member(type = type, name = name))
+del struct_get_members
+
+@method(AST.Specifier)
+def specifier_get_type(self):
+ print(self)
+ raise NotImplementedError
+@method(AST.StructSpecifier)
+def specifier_get_type(self):
+ children = []
+ if len(self.children) >= 2:
+ for i in self.children[1].children:
+ i.struct_get_members(children)
+ return AST.TypeStruct(
+ name = self.children[0].text[0],
+ children = children
+ )
+@method(AST.UnionSpecifier)
+def specifier_get_type(self):
+ children = []
+ for i in self.children[1].children:
+ i.struct_get_members(children)
+ return AST.TypeUnion(
+ name = self.children[0].text[0],
+ children = children
+ )
+del specifier_get_type
+
@method(AST.DeclarationSpecifierList)
def get_type(self):
type_specifiers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for i in self.children:
- if isinstance(i, AST.TypeSpecifier):
- type_specifiers[i.n] += 1
+ if not isinstance(i, AST.TypeSpecifier):
+ return i.specifier_get_type()
+ type_specifiers[i.n] += 1
return type_specifiers_to_type[tuple(type_specifiers)]
@method(AST.SpecifierQualifierList)
def get_type(self):
type_specifiers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for i in self.children:
- if isinstance(i, AST.TypeSpecifier):
- type_specifiers[i.n] += 1
+ if not isinstance(i, AST.TypeSpecifier):
+ return i.specifier_get_type()
+ type_specifiers[i.n] += 1
return type_specifiers_to_type[tuple(type_specifiers)]
del get_type