python抽象語法樹的遍歷

2021-10-11 02:02:18 字數 4333 閱讀 5164

遍歷語法樹獲取資訊:

語法樹node

for node in ast.walk(tree):

if isinstance(node, ast.functiondef):

print(node.name)

class codevisitor(ast.nodevisitor):

def generic_visit(self, node):

print type(node).__name__

ast.nodevisitor.generic_visit(self, node)

def visit_functiondef(self, node):

print type(node).__name__

ast.nodevisitor.generic_visit(self, node)

def visit_assign(self, node):

print type(node).__name__

ast.nodevisitor.generic_visit(self, node)

當visit_***這個方法存在時,呼叫self.visit_***方法訪問ast.node中的***型別結點

否則的話,呼叫self.generic_visit

generic_visit :ast類中實現,呼叫self.visit訪問子結點

具體應用

with open(

'func_def.py','r'

) as f:

content=f.read(

)t=ast.parse(content)

1、列印抽象語法樹

def str_node(node):

if isinstance(node,ast.ast):

fields=

[(name,str_node(val))

for name,val in ast.iter_fields(node)

if name not in

('left','right')]

rv =

'%s(%s' % (node.__class__.__name__, ', '.join(

'%s=%s' % field for field in fields))

return rv + ')'

else:

return repr(node)

def ast_visit(node, level=0):

print(

' ' * level + str_node(node))

for field, value in ast.iter_fields(node):

if isinstance(value, list):

for item in value:

if isinstance(item, ast.ast):

ast_visit(item, level=level+1)

elif isinstance(value, ast.ast):

ast_visit(value, level=level+1)

#列印ast結點

ast_visitor(t)

2、列印ast所有結點的型別

class v(ast.nodevisitor):

def generic_visit(self, node):

print(type(node).__name__)

ast.nodevisitor.generic_visit(self,node)

x = v(

)x.visit(t)

module

functiondef

arguments

argarg

assign

name

store

binop

name

load

addname

load

return

name

load

functiondef

arguments

argarg

assign

name

store

binop

name

load

subname

load

return

name

load

ifcompare

name

load

eqconstant

expr

call

name

load

call

name

load

constant

constant

3、遍歷結點時跳過不想要的結點

例如:跳過load結點

class w(v):

def visit_load(self, node):

pass

y = w(

)y.visit(t)

module

functiondef

arguments

argarg

assign

name

store

binop

name

addname

return

name

functiondef

arguments

argarg

assign

name

store

binop

name

subname

return

name

ifcompare

name

eqconstant

expr

call

name

call

name

constant

constant

4、對某型別結點進行處理

例如:訪問name結點時具體列印name結點的id

class z(w):

def visit_name(self,node):

print(

"name:",node.id)

z = z(

)z.visit(t)

module

functiondef

arguments

argarg

assign

name: a

binop

name: x

addname: y

return

name: a

functiondef

arguments

argarg

assign

name: b

binop

name: x

subname: y

return

name: b

ifcompare

name: __name__

eqconstant

expr

call

name: print

call

name: add

constant

constant

5、遍歷語法樹過程中儲存資訊,對想要的結點override而不用修改generic_visit

例如:把所有name節點的id屬性放入set中

class allnames(ast.nodevisitor):

def visit_module(self, node):

self.names = set(

) self.generic_visit(node)

print(sorted(self.names))

def visit_name(self,node):

self.names.add(node.id)

allnames=allnames(

)allnames.visit(t)

['__name__', 'a', 'add', 'b', 'print', 'x', 'y'

]

部分參考文件:

getting to and from ast|meet the nodes|working on the tree|examples of working on with asts

編譯抽象語法樹

編譯抽象語法樹 對大多數開發人員來說,編譯就意謂著產生本地 給人感覺就是乙個字,難。但是,並不一定要產生本地 對於 dsl,通常產生其他更加通用的程式語言。net 框架提供幾個把抽象語法樹編譯成程式的功能。技術的選擇取決於幾個因素。例如,如果語言針對的是開發人員,那麼,生成文字檔案就足夠了,內容可以...

python實現樹的遍歷

二叉樹的遍歷是指按照某種順序依次訪問樹中的所有節點一次。四種遍歷方式分別是 先序遍歷 中序遍歷 後序遍歷 層序遍歷。其中前三種屬於深度優先遍歷 dfs 後一種屬於廣度優先遍歷 bfs 首先宣告節點類 class treenode def init self,x self.val x self.lef...

python遍歷目錄樹

假定你希望對某個資料夾中的所有檔案改名,包括該資料夾中所有子資料夾中的所有檔案。也就是說,你希望遍歷目錄樹,處理遇到的每個檔案。寫程式完成這件事,可能需要一些技巧。好在,python 提供了乙個函式,替你處理這個過程。請看 c delicious 資料夾及其內容,如圖 9 1 所示。這裡有乙個例子程...