|
From: Baptiste L. <bl...@us...> - 2004-08-08 11:52:58
|
Update of /cvsroot/cpptool/CppParser/src/pyrfta In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8063/src/pyrfta Modified Files: ast.py dumpast.py nodetools.py Added Files: dumpnodetree.py Log Message: * renamed dumpast to dumpnodetree * added dumpast to dump the node tree ast wrapper Index: nodetools.py =================================================================== RCS file: /cvsroot/cpptool/CppParser/src/pyrfta/nodetools.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** nodetools.py 7 Aug 2004 22:56:20 -0000 1.1 --- nodetools.py 8 Aug 2004 11:52:40 -0000 1.2 *************** *** 6,9 **** --- 6,14 ---- return node.childAt(0) + def tryGetFirstChild( node ): + if node.childCount == 0: + return None + return node.childAt(0) + def getFirstChildNamed( node, name, exception_if_not_found = True ): for child in node.enumChildren(): Index: ast.py =================================================================== RCS file: /cvsroot/cpptool/CppParser/src/pyrfta/ast.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ast.py 8 Aug 2004 08:57:57 -0000 1.2 --- ast.py 8 Aug 2004 11:52:40 -0000 1.3 *************** *** 1,8 **** import nodetools ! class ASTNode: pass ! class Statement(ASTNode): pass --- 1,8 ---- import nodetools ! class ASTElement: pass ! class Statement(ASTElement): pass *************** *** 17,23 **** class TranslationUnit(Declarations): def __init__( self, translation_unit_node ): ! Declarations.__init__( translation_unit_node ) ! class Declaration(ASTNode): def __init__( self, node ): self.node = node --- 17,23 ---- class TranslationUnit(Declarations): def __init__( self, translation_unit_node ): ! Declarations.__init__( self, translation_unit_node ) ! class Declaration(ASTElement): def __init__( self, node ): self.node = node *************** *** 92,98 **** 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 ): --- 92,95 ---- *************** *** 101,107 **** # 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 --- 98,108 ---- # self.type_specifier_node = nodetools.getFirstChildNamed( declaration_specifier_node, 'type_specifier' ) + class FriendDeclaration(StandardDeclaration): + pass # same as StandardDeclaration + class TypeSpecifier(ASTElement): def __init__( self, type_specifier_node, type ): ! self.node = type_specifier_node ! self.cv_qualifiers_nodes = nodetools.getChildrenNamed( type_specifier_node, 'cv_qualifiers' ) # const/volatile self.type = type *************** *** 196,203 **** class FunctionDefinition(Declaration): ! pass class ASTBuilder: def __init__( self ): --- 197,285 ---- class FunctionDefinition(Declaration): ! def __init__( self, function_def_node ): ! Declaration.__init__( self, function_def_node ) ! self.return_type = None ! self.body = None + def setReturnType( self, return_type ): + self.return_type = return_type + def setBody( self, body ): + self.body = body + class FunctionReturnType(Type): + def __init__( self, node ): + Type.__init__( self, node ) + + ## ################################################################## + ## ################################################################## + ## AST Statements + ## ################################################################## + ## ################################################################## + + class Statement(ASTElement): + def __init__( self, statement_node ): + self.node = statement_node + + class CompoundStatement(Statement): + def __init__( self, compound_node ): + Statement.__init__( self, compound_node ) + self.statements = [] + + def addStatement( self, statement ): + self.statements.append( statement ) + + class ErrorStatement(Statement): + pass + class LabelStatement(Statement): + pass + + class CaseStatement(Statement): + pass + + class DefaultStatement(Statement): + pass + + class IfStatement(Statement): + pass + + class SwitchStatement(Statement): + pass + + class WhileStatement(Statement): + pass + + class DoWhileStatement(Statement): + pass + + class ForStatement(Statement): + pass + + class BreakStatement(Statement): + pass + + class ContinueStatement(Statement): + pass + + class ReturnStatement(Statement): + pass + + class GotoStatement(Statement): + pass + + class ExpressionStatement(Statement): + pass + + class DeclarationStatement(Statement): + def __init__( self, node ): + Statement.__init__( self, node ) + self.declaration = None + + def setDeclaration( self, declaration ): + self.declaration = declaration + + class TryBlockStatement(Statement): + pass + class ASTBuilder: def __init__( self ): *************** *** 231,244 **** 'member_error' : self.buildMemberErrorDeclaration } 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 --- 313,346 ---- 'member_error' : self.buildMemberErrorDeclaration } + self.statement_builders = { + 'compound_statement' : self.buildCompoundStatement, + 'error_statement' : self.buildErrorStatement, + 'label_statement' : self.buildLabelStatement, + 'case_statement' : self.buildCaseStatement, + 'default_statement' : self.buildDefaultStatement, + 'if_statement' : self.buildIfStatement, + 'switch_statement' : self.buildSwitchStatement, + 'while_statement' : self.buildWhileStatement, + 'dowhile_statement' : self.buildDoWhileStatement, + 'for_statement' : self.buildForStatement, + 'break_statement' : self.buildBreakStatement, + 'continue_statement' : self.buildContinueStatement, + 'return_statement' : self.buildReturnStatement, + 'goto_statement' : self.buildGotoStatement, + 'expression_statement' : self.buildExpressionStatement, + 'declaration_statement' : self.buildDeclarationStatement, + 'try_block' : self.buildTryBlockStatement + } def buildTranslationUnit( self, root ): assert root.name == 'translation_unit' ast = TranslationUnit( root ) ! self.buildDeclarations( ast, root ) ! return ast def buildDeclarations( self, ast, declarations_parent ): ! declarations = nodetools.getFirstChildNamed( declarations_parent, 'declarations' ) for declaration in declarations.enumChildren(): ! ast.addDeclaration( self.declaration_builders[ declaration.name ]( declaration ) ) return ast *************** *** 273,277 **** def buildSimpleDeclaration( self, declaration ): ! declaration_specifier = nodetools.getFirstChild( declaration, False ) if declaration_specifier: if declaration_specifier.name == 'typedef_specifier': --- 375,379 ---- def buildSimpleDeclaration( self, declaration ): ! declaration_specifier = nodetools.tryGetFirstChild( declaration ) if declaration_specifier: if declaration_specifier.name == 'typedef_specifier': *************** *** 286,298 **** 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' ) --- 388,400 ---- def buildTypedefSimpleDeclaration( self, declaration, typedef_specifier ): ! ast = TypedefDeclaration( declaration ) return ast def buildFriendSimpleDeclaration( self, declaration, friend_specifier ): ! ast = FriendDeclaration( declaration ) return ast def buildStandardSimpleDeclaration( self, declaration, declaration_specifier ): ! ast = StandardDeclaration( declaration ) ast.setDeclarationSpecifierNode( declaration_specifier ) type_specifier_node = nodetools.getFirstChildNamed( declaration_specifier, 'type_specifier' ) *************** *** 355,359 **** def buildMemberErrorDeclaration( self, declaration ): ! return MemberErrorDeclaration( declaration ): def buildForwardClassType( self, type_node ): --- 457,461 ---- def buildMemberErrorDeclaration( self, declaration ): ! return MemberErrorDeclaration( declaration ) def buildForwardClassType( self, type_node ): *************** *** 367,370 **** --- 469,485 ---- def buildFunctionDefinition( self, declaration ): + ast = FunctionDefinition( declaration ) + function_return_type_node = nodetools.getFirstChildNamed( declaration, 'function_return_type' ) + if function_return_type_node: + ast.setReturnType( FunctionReturnType(function_return_type_node) ) + + ## 'declarator_id' + ## 'braced_declarator' + + body_node = nodetools.getFirstChildNamed( declaration, 'compound_statement' ) + if body_node: + ast.setBody( self.buildCompoundStatement( body_node ) ) + + # ? function_return_type # declarator_id *************** *** 372,375 **** # ? cv_qualifiers # ? exception_specification ! pass ! \ No newline at end of file --- 487,555 ---- # ? cv_qualifiers # ? exception_specification ! return ast ! ! ##################################### ! ## Statements ! ##################################### ! ! def buildErrorStatement( self, statement ): ! return ErrorStatement( statement ) ! ! def buildCompoundStatement( self, statement ): ! ast = CompoundStatement( statement ) ! for child in statement.enumChildren(): ! if not child.hasValidToken(): ! statement = self.statement_builders[ child.name ]( child ) ! ast.addStatement( statement ) ! return ast ! ! def buildLabelStatement( self, statement ): ! return LabelStatement( statement ) ! ! def buildCaseStatement( self, statement ): ! return CaseStatement( statement ) ! ! def buildDefaultStatement( self, statement ): ! return DefaultStatement( statement ) ! ! def buildIfStatement( self, statement ): ! return IfStatement( statement ) ! ! def buildSwitchStatement( self, statement ): ! return SwitchStatement( statement ) ! ! def buildWhileStatement( self, statement ): ! return WhileStatement( statement ) ! ! def buildDoWhileStatement( self, statement ): ! return DoWhileStatement( statement ) ! ! def buildForStatement( self, statement ): ! return ForStatement( statement ) ! ! def buildBreakStatement( self, statement ): ! return BreakStatement( statement ) ! ! def buildContinueStatement( self, statement ): ! return ContinueStatement( statement ) ! ! def buildReturnStatement( self, statement ): ! return ReturnStatement( statement ) ! ! def buildGotoStatement( self, statement ): ! return GotoStatement( statement ) ! ! def buildExpressionStatement( self, statement ): ! return ExpressionStatement( statement ) ! ! def buildDeclarationStatement( self, statement ): ! ast = DeclarationStatement( statement ) ! declaration_node = nodetools.getFirstChild( statement ) ! declaration = self.declaration_builders[ declaration_node.name ]( declaration_node ) ! ast.setDeclaration( declaration ) ! return ast ! ! def buildTryBlockStatement( self, statement ): ! return TryBlockStatement( statement ) ! ! --- NEW FILE: dumpnodetree.py --- import sys import pycppparser as cprs source = file( sys.argv[1], "rt" ).read() grammar_path = 'cpp_grammar.txt' parser = cprs.makeParser( grammar_path ) translation_unit = parser.parse( source ) print translation_unit.treeStr() Index: dumpast.py =================================================================== RCS file: /cvsroot/cpptool/CppParser/src/pyrfta/dumpast.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** dumpast.py 7 Aug 2004 22:55:07 -0000 1.1 --- dumpast.py 8 Aug 2004 11:52:40 -0000 1.2 *************** *** 1,4 **** --- 1,74 ---- import sys import pycppparser as cprs + import ast + + def _getClassName( obj ): + class_name = str(obj.__class__).split('.')[-1] + return class_name + + class ASTInfo: + def __init__( self, name_or_ast = None ): + self.__attributes = {} + self.__children = [] + if type(name_or_ast) == str: + self.__name = name_or_ast + else: + self.__name = _getClassName( ast ) + + def name( self ): + return self.__name + + def attr( self, name, value = None ): + return self.__attributes.setdefault( name, value ) + + def attributes( self ): + return self.__attributes.items() + + class ASTInfoBuilder: + def visitASTNode( self, ast ): + visit_method = 'visit' + _getClassName(ast) + print 'visiting ', visit_method + return getattr( self, visit_method )( ast ) + + def visitTranslationUnit( self, ast ): + info = ASTInfo( ast ) + return self.handleDeclarations( info, ast ) + + def handleDeclarations( self, info, ast ): + info.attr( 'declarations', [] ) + for declaration in ast.declarations: + info.attr('declarations').append( self.visitASTNode( declaration ) ) + return info + + def visitFunctionDefinition( self, ast ): + name = (ast.body and 'FunctionDefinition') or 'FunctionPrototype' + info = ASTInfo( name ) + return info + + + + def printASTInfo( info, indent = 0 ): + margin = '| ' * indent + indent += 1 + print margin + info.name() + '[' + attribute_margin = margin + '|-' + for name, value in info.attributes(): + if type(value) == ASTInfo: + printASTInfo( value, indent ) + elif type(value) == type([]): + printASTInfoChildren( name, value, attribute_margin, indent-1 ) + else: + print attribute_margin + name + ': ' + str(value) + print margin + ']' + + def printASTInfoChildren( name, children, attribute_margin, indent ): + margin = '| ' * indent + indent += 2 + print margin + '|-' + name + ': ' + '[' + for child in children: + printASTInfo( child, indent ) + print margin + '| ]' + + source = file( sys.argv[1], "rt" ).read() *************** *** 6,9 **** grammar_path = 'cpp_grammar.txt' parser = cprs.makeParser( grammar_path ) ! translation_unit = parser.parse( source ) ! print translation_unit.treeStr() --- 76,84 ---- grammar_path = 'cpp_grammar.txt' parser = cprs.makeParser( grammar_path ) ! print 'Parsing', sys.argv[1] ! translation_unit_node = parser.parse( source ) ! print 'Building ast..' ! ! ast = ast.ASTBuilder().buildTranslationUnit( translation_unit_node ) ! info = ASTInfoBuilder().visitTranslationUnit( ast ) ! printASTInfo( info ) \ No newline at end of file |