You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ply与ast模块构建抽象语法树的示例或文档有哪些?

使用PLY与Python ast模块构建语法树的实用示例

以下是最小可运行的实现示例,可直接运行调试理解逻辑:

前置依赖安装

执行命令安装所需模块:
pip install ply astor

完整实现示例

1. 词法分析器实现

import ply.lex as lex
import ast

# 定义词法单元类型
tokens = (
    'NUMBER',
    'PLUS',
    'MINUS',
    'TIMES',
    'DIVIDE',
    'LPAREN',
    'RPAREN',
)

# 定义符号匹配规则
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_LPAREN = r'\('
t_RPAREN = r'\)'

def t_NUMBER(t):
    r'\d+'
    t.value = int(t.value)
    return t

# 忽略空白字符
t_ignore = ' \t'

def t_error(t):
    print(f"非法字符: {t.value[0]}")
    t.lexer.skip(1)

lexer = lex.lex()

2. 语法分析器实现(直接生成Python AST)

import ply.yacc as yacc

# 算术表达式优先级定义
precedence = (
    ('left', 'PLUS', 'MINUS'),
    ('left', 'TIMES', 'DIVIDE'),
)

def p_expression_plus(p):
    'expression : expression PLUS term'
    p[0] = ast.BinOp(left=p[1], op=ast.Add(), right=p[3])

def p_expression_minus(p):
    'expression : expression MINUS term'
    p[0] = ast.BinOp(left=p[1], op=ast.Sub(), right=p[3])

def p_expression_term(p):
    'expression : term'
    p[0] = p[1]

def p_term_times(p):
    'term : term TIMES factor'
    p[0] = ast.BinOp(left=p[1], op=ast.Mult(), right=p[3])

def p_term_div(p):
    'term : term DIVIDE factor'
    p[0] = ast.BinOp(left=p[1], op=ast.Div(), right=p[3])

def p_term_factor(p):
    'term : factor'
    p[0] = p[1]

def p_factor_num(p):
    'factor : NUMBER'
    p[0] = ast.Constant(value=p[1])

def p_factor_expr(p):
    'factor : LPAREN expression RPAREN'
    p[0] = p[2]

def p_error(p):
    print(f"语法错误在: {p.value if p else '文件末尾'}")

parser = yacc.yacc()

3. 效果测试

import astor

# 测试用输入表达式
input_expr = "3 + 4 * (10 - 2)"
# 解析生成AST
ast_root = parser.parse(input_expr)
# 补全Python AST必填的位置信息
ast.fix_missing_locations(ast_root)

# 打印生成的Python代码
print(astor.to_source(ast_root))
# 执行AST验证结果
print(eval(compile(ast_root, filename='<ast>', mode='eval')))

核心注意事项

  • 所有Python AST节点的属性需符合Python官方ast模块定义,可先通过ast.dump(ast.parse("对应Python代码"), indent=2)打印目标结构,再对应写PLY生成规则
  • 若要转译为Python之外的语言,可自行遍历生成的AST节点,按目标语言的语法规则拼接输出即可
  • 复杂语法可通过扩展tokens、语法规则,对应生成ast.Assign、ast.FunctionDef、ast.If等节点实现

内容的提问来源于stack exchange,提问作者beton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 02:36:03