如何在Python中解析完整/不完整语句与表达式为Token流和语法树?
在Python中解析代码为Token流和语法树
Python标准库提供了几个原生模块,可直接完成代码解析为Token流、语法树的需求,无需依赖第三方工具:
1. 提取Token流:使用tokenize模块
tokenize模块能将Python代码拆解为语法Token(如关键字、标识符、运算符、字符串等),同时保留行号、列号等位置信息。
示例:从字符串提取Token流
import tokenize from io import StringIO def extract_tokens(code): # 用StringIO模拟文件对象,适配tokenize的读取方式 with StringIO(code) as f: # generate_tokens返回TokenInfo迭代器,包含Token的类型、内容、位置等 for token in tokenize.generate_tokens(f.readline): token_type_name = tokenize.tok_name[token.type] print(f"Token类型: {token_type_name}, 内容: '{token.string}', 位置: {token.start}") # 测试完整代码 extract_tokens("x = 1 + 2") # 测试不完整代码 extract_tokens("def bar():")
运行后会输出每个Token的详细信息,若需过滤注释、空行等无关Token,可在循环中判断token.type是否为tokenize.COMMENT或tokenize.NL,直接跳过即可。
2. 生成语法树:使用ast模块
ast模块可将Python代码解析为抽象语法树(AST),你可以遍历、分析甚至修改这个树结构,用于代码检查、重构等场景。
示例:生成并遍历语法树
import ast def generate_ast(code, mode='exec'): try: # mode参数:'exec'处理完整语句,'eval'处理表达式 tree = ast.parse(code, mode=mode) # ast.dump()将节点转为可读字符串,方便查看结构 print(ast.dump(tree, indent=2)) # 也可自定义NodeVisitor遍历节点 class ASTVisitor(ast.NodeVisitor): def visit_Assign(self, node): print(f"发现赋值语句:目标变量{ast.dump(node.targets[0])}") self.generic_visit(node) visitor = ASTVisitor() visitor.visit(tree) except SyntaxError as e: print(f"语法错误:{e}") # 测试完整语句 generate_ast("x = 1 + 2") # 测试表达式 generate_ast("1 + 2", mode='eval')
3. 处理不完整代码片段
直接用ast.parse处理未写完的代码(如未闭合的括号、未完成的函数定义)会抛出SyntaxError,此时可借助codeop模块判断代码是否完整:
示例:识别并处理不完整代码
import codeop import ast def parse_incomplete_code(code): # compile_command模拟交互式解释器逻辑,返回None表示代码不完整 compiled_result = codeop.compile_command(code) if compiled_result is None: print("代码不完整,请补充输入") else: tree = ast.parse(code) print("生成语法树成功:", ast.dump(tree, indent=2)) # 测试不完整代码 parse_incomplete_code("def foo():") # 测试完整代码 parse_incomplete_code("def foo(): return 42")
内容的提问来源于stack exchange,提问作者user3310334
相关产品推荐
相关产品推荐

