From b7d0db3a5b45175c788485de54ea59955920caa4 Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Sun, 19 Jan 2020 14:08:36 +1100 Subject: [PATCH] Update hacky hard coded paths to pilex/piyacc/pitree, add struct translation --- Makefile | 8 ++-- ansi_c.l | 6 +-- ansi_c.t | 114 +++++++++++++++++++++++++++++++++++++++++++++++++------ ansi_c.y | 2 +- 4 files changed, 111 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index e35fcf9..ccbb7dd 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,16 @@ all: element.py lex_yy.py t_def.py y_tab.py -element.py: ../pitree.git/skel/element.py +element.py: ../pitree/ndcode/pitree/skel/element.py cat $< >$@ lex_yy.py: ansi_c.l - ../pilex.git/pilex.py --element --python $< + ../pilex/pilex.py --element --python $< t_def.py: ansi_c.t - ../pitree.git/pitree.py --python $< + PYTHONPATH=../pitree ../pitree/ndcode/pitree/cli.py --python $< y_tab.py: ansi_c.y - ../piyacc.git/piyacc.py --element --python $< + ../piyacc/piyacc.py --element --python $< clean: rm -f element.py lex_yy.py t_def.py y_tab.py diff --git a/ansi_c.l b/ansi_c.l index 099f1b1..e037240 100644 --- a/ansi_c.l +++ b/ansi_c.l @@ -22,8 +22,8 @@ ES (\\(['"\?\\abfnrtv]|[0-7]{1,3}|x[a-fA-F0-9]+)) WS [ \t\v\n\f] %{ -import t_def -import y_tab + import t_def + import y_tab %} %% @@ -80,7 +80,7 @@ import y_tab "_Thread_local" return y_tab.THREAD_LOCAL "__func__" return y_tab.FUNC_NAME -"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" { +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|u?int(8|16|32|64)_t { # THIS IS A HACK FOR NOW return y_tab.TYPEDEF_NAME } diff --git a/ansi_c.t b/ansi_c.t index 3083146..4937513 100644 --- a/ansi_c.t +++ b/ansi_c.t @@ -16,6 +16,11 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +%{ + import element + import sys +%} + %% class AST { @@ -35,6 +40,7 @@ class AST { int precedence = -1; bool right_to_left = False; }; + class Specifier; /* type analysis */ class Type; class TypeVoid: Type; @@ -62,6 +68,15 @@ class AST { 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; @@ -86,7 +101,7 @@ class AST { class DesignatorInitializerList: InitializerOrExpression; class DesignatorListEqualsEmpty; class DesignatorList; - class EnumSpecifier; + class EnumSpecifier: Specifier; class Enumerator; class EnumeratorList; class EqualsInitializerEmpty; @@ -149,7 +164,7 @@ class AST { class ExpressionSubtract: ExpressionBinary; class ExpressionSubtractAssignment: ExpressionBinary; class FunctionDefinition: DeclarationOrStatement; - class FunctionSpecifier { + class FunctionSpecifier: Specifier { int n = -1; }; class GenericAssociation; @@ -179,35 +194,39 @@ class AST { 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', @@ -219,6 +238,7 @@ class Context: 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 @@ -265,7 +285,7 @@ octal_prefix = set( ) 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): @@ -279,6 +299,40 @@ 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): @@ -829,6 +883,9 @@ def translate_zero(self, context): [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) @@ -887,19 +944,54 @@ def translate_block_item_list(self, context): 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 diff --git a/ansi_c.y b/ansi_c.y index 11dd954..7eb80d8 100644 --- a/ansi_c.y +++ b/ansi_c.y @@ -20,7 +20,7 @@ %expect 2 %{ -import t_def + import t_def %} %% -- 2.34.1