PyXR

C:\Python24\Lib\site-packages\pyxr \ astCrawler.py



0001 # Copyright 2003, Grant T. Olson, see License.txt for details
0002 
0003 import types
0004 import parser
0005 import token
0006 import symbol
0007 import sys
0008 
0009 class astCrawler:
0010     """
0011     ABC for ast processing.
0012 
0013     This turns input text into an ast and then crawls through it.
0014 
0015     There are two types of nodes in a python AST:
0016         SYMBOLs are nonterminal nodes that consist of a SYMBOL_ID and a list of other nodes
0017         TOKENs are terminal nodes that consist of a TOKEN_ID and a string that represents token value
0018 
0019     Process strips a node into two pieces, the ID and the list of nodes or tokenString
0020     it dispatches this to handler functions by looking up the nodeID in the self.handlers dict
0021     if no entry is found, it calls the default handler.
0022 
0023     Calling process with no params starts at the top of the tree.    
0024     """
0025     def __init__(self, text):
0026         self.ast = parser.ast2tuple(parser.suite(text))
0027         self.handlers = {}
0028         self.registerHandlers()
0029     
0030     def simplify(self, tuple):
0031         """
0032         Python uses alot of intermediate nodes to simplify tree construction.
0033         This will factor out intermediate nodes that only contain a single child
0034         to give us humans some chance at being able to interpret junk
0035         """
0036         if type(tuple) == types.IntType:
0037             return tuple
0038         elif type(tuple) == types.StringType:
0039             return tuple
0040         elif type(tuple) == types.TupleType:
0041             if len(tuple) == 2 and type(tuple[0]) == types.IntType and type(tuple[1]) == types.TupleType:
0042                 return self.simplify(tuple[1])
0043             else:
0044                 return map(self.simplify, tuple)
0045         else:
0046             raise Exception("Invalid type")
0047 
0048 
0049 
0050     def simplifyWithName(self, tuple):
0051         """
0052         Same as simplify, but it shows the symbol or token name instead of ID number
0053         """
0054         if type(tuple) == types.IntType:
0055             return self.numberToName(tuple)
0056         elif type(tuple) == types.StringType:
0057             return tuple
0058         elif type(tuple) == types.TupleType:
0059             if len(tuple) == 2 and type(tuple[0]) == types.IntType and type(tuple[1]) == types.TupleType:
0060                 return self.simplifyWithName(tuple[1])
0061             else:
0062                 return map(self.simplifyWithName, tuple)
0063         else:
0064             raise Exception("Invalid type")
0065 
0066     def numberToName(self, number):
0067         """
0068         Turns a node ID number into the string description from token and symbol packages
0069         """
0070         if token.tok_name.has_key(number):
0071             return token.tok_name[number]
0072         elif symbol.sym_name.has_key(number):
0073             return symbol.sym_name[number]
0074         else:
0075             return "UNKNOWN SYMBOL %d" % tuple
0076         
0077     def process(self, ast=None):
0078         """
0079         Recursively process the ast tree and dispatch to whatever handlers we've instituted in subclasses
0080         """
0081         if not ast:
0082             ast = self.ast
0083         if type(ast) == types.TupleType:
0084             nodeType = ast[0]
0085             nodeParams = ast[1:]
0086             nodeHandler = self.handlers.get(nodeType, self.defaultHandler)
0087             nodeHandler(nodeParams)
0088         else:
0089             raise Exception("Process error: Type is not a tuple %s" % ast)
0090 
0091     ###
0092     ### HANDLERS
0093     ###
0094 
0095     def registerHandlers(self):
0096         """
0097         break registration logic out of the constructor so we can
0098         deal with subclasses properly
0099         """        
0100         pass
0101         
0102     def defaultHandler(self, params):
0103         """
0104         process all nodes that we don't know about
0105         """
0106         for item in params:
0107             if type(item) == types.TupleType: # recursively process nodes
0108                 self.process(item)
0109             elif type(item) == types.StringType: # this is the value of a token
0110                 self.defaultHandleToken(item)
0111             else:
0112                 raise Exception("Invalid node parameters")
0113             
0114     def defaultHandleToken(self, item):
0115         """Override this function so we can keep default handler core logic"""
0116         pass
0117 
0118 
0119 
0120 
0121 

Generated by PyXR 0.9.4
SourceForge.net Logo