|
From: Baptiste L. <bl...@us...> - 2004-08-07 22:56:30
|
Update of /cvsroot/cpptool/CppParser/src/pyrfta In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7098/src/pyrfta Added Files: ast.py nodetools.py Log Message: * started implementing a wrapper around the AST (typed node) --- NEW FILE: nodetools.py --- import pycppparser as cprs def getFirstChild( node ): if node.childCount == 0: raise LogicError( "Fail to get first chil in node %s" % node ) return node.childAt(0) def getFirstChildNamed( node, name, exception_if_not_found = True ): for child in node.enumChildren(): if child.name == name: return child if exception_if_not_found: raise LogicError( "Fail to find children named '%s' in node %s" % (name,node) ) return None def getChildrenNamed( node, name ): return [ child for child in node.enumChildren() if child.name == name ] def getFirstIdentifierChildNode( node, exception_if_not_found = True ): for child in node.enumChildren(): if child.category == cprs.TK_IDENTIFIER: return child if exception_if_not_found: raise LogicError( "Fail to find identifier child in node %s" % node ) return None def getFirstStringChildNode( node, exception_if_not_found = True ): for child in node.enumChildren(): if child.category == cprs.TK_STRING: return child if exception_if_not_found: raise LogicError( "Fail to find string child in node %s" % node) return None --- NEW FILE: ast.py --- import nodetools class ASTNode: pass class Statement(ASTNode): pass class Declarations: def __init__( self, node ): self.node = node self.declarations = [] def addDeclaration( self, declaration ): self.declarations.append( declaration ) class TranslationUnit(Declarations): def __init__( self, translation_unit_node ): Declarations.__init__( translation_unit_node ) class Declaration(ASTNode): def __init__( self, node ): self.node = node class NamespaceAliasDef(Declaration): def __init__( self, namespace_node ): Declaration.__init__( self, namespace_node ) self.id_node = nodetools.getFirstIdentifierChildNode( namespace_node ) self.alias_node = nodetools.getFirstChildNamed( namespace_node, 'namespace_specifier' ) def name( self ): return self.id_node.text def aliasNode( self ): # namespace... return self.alias_node class UsingDeclaration(Declaration): # very similar to NamespaceAliasDef def __init__( self, using_node ): Declaration.__init__( self, using_node ) self.using_id_node = nodetools.getFirstChildNamed( using_node, 'using_id' ) def usingIdNode( self ): # qualified id return self.using_id_node class UsingDirective(Declaration): def __init__( self, using_node ): Declaration.__init__( self, using_node ) self.namespace_id_node = nodetools.getFirstChildNamed( using_node, 'namespace_specifier' ) def usingIdNode( self ): # namespace... return self.namespace_id_node class Initializer(ASTElement): def __init( self, node ): self.node = node class AssignInitializer(Initializer): # ~ n assignment_expression or array/struct initializer pass class ConstructorInitializer(Initializer): # n assignment_expression pass class Declarator: def __init__( self, declaration, init_declarator_node ): self.declaration = declaration self.declarator_node = nodetools.getFirstChildNamed( init_declarator_node, 'declarator' ) self.initializer = None assign_initializer_node = nodetools.getFirstChildNamed( init_declarator_node, 'assign_initializer', False ) if assign_initializer_node: self.initializer = AssignInitializer( assign_initializer_node ) expression_list_node = nodetools.getFirstChildNamed( init_declarator_node, 'expression_list', False ) if expression_list_node: self.initializer = ConstructorInitializer( expression_list_node ) class SimpleDeclaration(Declaration): def __init__( self, declaration_node ): Declaration.__init__( self, declaration_node ) # type_specifiers # typedef + type specifier # or friend + standard # or standard # storage class specifier: mutable, static... # function specifier (inline, explicit, virtual) # type specifier # init_declarators pass class TypedefDeclaration(SimpleDeclaration): def setDeclarationSpecifierNode( self, declaration_specifier_node ): self.type_specifier_node = nodetools.getFirstChildNamed( declaration_specifier_node, 'type_specifier' ) class FriendDeclaration(StandardDeclaration): pass # same as StandardDeclaration class StandardDeclaration(SimpleDeclaration): def setDeclarationSpecifierNode( self, declaration_specifier_node ): self.storage_class_node = nodetools.getFirstChildNamed( declaration_specifier_node, 'storage_class_specifier', False ) self.function_spec_node = nodetools.getFirstChildNamed( declaration_specifier_node, 'function_specifier', False ) # self.type_specifier_node = nodetools.getFirstChildNamed( declaration_specifier_node, 'type_specifier' ) class TypeSpecifier(ASTElement): def __init__( self, type_specifier_node, type ): self.cv_qualifiers_nodes = nodetools.getChildrenNamed( 'cv_qualifiers' ) # const/volatile self.type = type class Type(...): def __init__( self, node ): self.node = node class FundamentalType(Type): pass class TypeNameType(Type): pass class EnumType(Type): def __init__( self, enum_node ): Type.__init__( enum_node ) self.id_node = nodetools.getFirstIdentifierChildNode( enum_node, False ) self.definitions = [] def name( self ): if self.id_node: return self.id_node.name return None def addDefinition( self, definition ): self.definitions.append( definition ) class EnumDefinition(ASTElement): def __init__( self, enum_definition_node ): self.node = enum_definition_node class LinkageSpecificationBase: def __init__( self ): self.linkage_type_node = nodetools.getFirstStringChildNode( self.node ) def linkageType( self ): return self.linkage_type_node.text class LinkageSpecification(Declaration,LinkageSpecificationBase): def __init__( self, linkage_spec_node ): Declaration.__init__( self ) LinkageSpecificationBase.__init__( self ) class LinkageSpecificationBlock(Declarations,LinkageSpecificationBase): def __init__( self, linkage_spec_node ): Declarations.__init__( self ) LinkageSpecificationBase.__init__( self ) class NamedNamespaceDef(Declarations): def __init__( self, namespace_node ): Declarations.__init__( namespace_node ) self.id_node = nodetools.getFirstIdentifierChildNode( namespace_node ) def name( self ): return self.id_node.text class AnonymousNamespaceDef(Declarations): pass # nothing else needed class FunctionDefinition(Declaration): pass class AggregateDeclaration(Declaration): pass class Type: pass class ASTBuilder: def __init__( self ): self.current = None self.declaration_builders = { 'simple_declaration' : self.buildSimpleDeclaration, 'named_namespace_def' : self.buildNamedNamespaceDef, 'unnamed_namespace_def' : self.buildAnonymousNamespaceDef, 'linkage_specification' : self.buildLinkageSpecification, 'function_definition' : self.buildFunctionDefinition, 'namespace_alias_def' : self.buildNamespaceAliasDef, 'using_declaration' : self.buildUsingDeclaration, 'using_directive' : self.buildUsingDirective } self.type_builders = { 'fundamental_type_specifier' : self.buildFundamentalType, 'type_name' : self.buildTypeNameType, 'enum_specifier': self.buildEnumType, 'class_specifier' : self.buildClassType, 'forward_class_specifier' : self.buildForwardClassType, 'forward_enum_specifier' : self.buildForwardEnumType, 'forward_typename_specifier' : self.buildForwardTypenameType } def buildTranslationUnit( self, root ): assert root.name == 'translation_unit' ast = TranslationUnit( root ) return self.buildDeclarations( ast, root ) def buildDeclarations( self, ast, declarations_parent ): declarations = nodetools.getFirstChildNamed( root, 'declarations' ) for declaration in declarations.enumChildren(): ast.addDeclaration( self.declaration_builders[ declaration.name ]() ) return ast def buildNamedNamespaceDef( self, declaration ): ast = NamedNamespaceDef( declaration ) return self.buildDeclarations( ast, declaration ) def buildAnonymousNamespaceDef( self, declaration ): ast = AnonymousNamespaceDef( declaration ) return self.buildDeclarations( ast, declaration ) def buildNamespaceAliasDef( self, declaration ): ast = NamespaceAliasDef( declaration ) return ast def buildUsingDeclaration( self, declaration ): ast = UsingDeclaration( declaration ) return ast def buildUsingDirective( self, declaration ): ast = UsingDeclaration( declaration ) return ast def buildLinkageSpecification( self, declaration ): declarations = nodetools.getFirstChildNamed( declaration, 'declarations', False ) if declarations is None: ast = LinkageSpecification( declaration ) # how to I build the child declaration ??? else: ast = LinkageSpecificationBlock( declaration ) self.buildDeclarations( ast, declaration ) return ast def buildSimpleDeclaration( self, declaration ): declaration_specifier = nodetools.getFirstChild( declaration, False ) if declaration_specifier: if declaration_specifier.name == 'typedef_specifier': return self.buildTypedefSimpleDeclaration( declaration, declaration_specifier ) elif declaration_specifier.name == 'friend_specifier': return self.buildFriendSimpleDeclaration( declaration, declaration_specifier ) elif declaration_specifier.name == 'declaration_specifier': return self.buildStandardSimpleDeclaration( declaration, declaration_specifier ) raise LogicError( "Don't know how to build simple declaration for: '%s'" % declaration_specifier.name ) else: return self.buildDeclaratorsSimpleDeclaration( declaration ) def buildTypedefSimpleDeclaration( self, declaration, typedef_specifier ): ast = TypedefDeclaration( self, declaration ) return ast def buildFriendSimpleDeclaration( self, declaration, friend_specifier ): ast = FriendDeclaration( self, declaration ) return ast def buildStandardSimpleDeclaration( self, declaration, declaration_specifier ): ast = StandardDeclaration( self, declaration ) ast.setDeclarationSpecifierNode( declaration_specifier ) type_specifier_node = nodetools.getFirstChildNamed( declaration_specifier, 'type_specifier' ) ast.type_specifier = self.buildTypeSpecifier( type_specifier_node ) return ast def buildTypeSpecifier( self, type_specifier ): index = 0 if type_specifier.childAt(0).name == 'cv_qualifiers': index = 1 type_node = type_specifier.childAt(index) type = self.type_builders[ type_node.name ]( type_node ) ast = TypeSpecifier( type_specifier, type ) return ast def buildFundamentalType( self, type_node ): return FundamentalType( type_node ) def buildTypeNameType( self, type_node ): return TypeNameType( type_node ) def buildEnumType( self, type_node ): ast = EnumType( self, type_node ) for definition in nodetools.getFirstChildNamed( type_node, 'enumerator_definitions' ).enumChildren(): ast.addDefinition( EnumDefinition( definition ) ) return ast def buildClassType( self, type_node ): pass def buildForwardClassType( self, type_node ): pass def buildForwardEnumType( self, type_node ): pass def buildForwardTypenameType( self, type_node ): pass def buildFunctionDefinition( self, declaration ): # ? function_return_type # declarator_id # function_parameters # ? cv_qualifiers # ? exception_specification pass |