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

如何使用Python中的PLY解析自定义编程语言的函数结构?

用PLY解析自定义语言的实现方案

1. 先安装依赖

确保你的环境里装了PLY:

pip install ply

2. 编写词法分析器(Lexer)

先把代码里的所有元素拆成可识别的Token,比如关键字、符号、标识符、数字:

import ply.lex as lex

# 定义需要识别的Token类型
tokens = (
    'ON',
    'MODIFYPROP',
    'RELATIVE',
    'COLON',
    'ARROW',
    'IDENTIFIER',
    'INTEGER',
)

# 匹配符号类Token
t_COLON = r':'
t_ARROW = r'=>'

# 匹配关键字(要先于标识符规则,避免被当成普通标识符)
def t_ON(t):
    r'on'
    return t

def t_MODIFYPROP(t):
    r'modifyProp'
    return t

def t_RELATIVE(t):
    r'relative'
    return t

# 匹配标识符(变量名、事件名这类)
def t_IDENTIFIER(t):
    r'[a-zA-Z_][a-zA-Z0-9_]*'
    return t

# 匹配整数并转成int类型
def t_INTEGER(t):
    r'\d+'
    t.value = int(t.value)
    return t

# 忽略空白、换行、制表符
t_ignore = ' \t\n'

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

# 生成词法分析器实例
lexer = lex.lex()

3. 编写语法分析器(Parser)

定义语法规则,把Token组合成有意义的语句结构,同时生成可后续处理的抽象语法树(AST):

import ply.yacc as yacc
from lexer import tokens  # 如果词法代码和语法代码放一块,可直接用tokens变量

# 顶层规则:整个程序由多个on语句组成
def p_program(p):
    '''program : program on_statement
               | on_statement'''
    p[0] = [p[2]] if len(p) == 2 else p[1] + [p[2]]

# on语句规则:模仿Python的def逻辑,冒号后接代码块
def p_on_statement(p):
    '''on_statement : ON IDENTIFIER COLON block'''
    p[0] = {
        'type': 'event_handler',
        'event': p[2],
        'actions': p[4]
    }

# 代码块规则:包含多个modifyProp语句
def p_block(p):
    '''block : block modify_prop_statement
             | modify_prop_statement'''
    p[0] = [p[1]] if len(p) == 2 else p[1] + [p[2]]

# 带relative参数的modifyProp语句
def p_modify_prop_relative(p):
    '''modify_prop_statement : MODIFYPROP RELATIVE IDENTIFIER ARROW INTEGER'''
    p[0] = {
        'type': 'modify_property',
        'relative': True,
        'property': p[3],
        'value': p[5]
    }

# 不带relative参数的modifyProp语句
def p_modify_prop(p):
    '''modify_prop_statement : MODIFYPROP IDENTIFIER ARROW INTEGER'''
    p[0] = {
        'type': 'modify_property',
        'relative': False,
        'property': p[2],
        'value': p[4]
    }

# 语法错误处理
def p_error(p):
    if p:
        print(f"语法错误在 token {p.type} (值: {p.value})")
    else:
        print("语法错误在输入末尾")

# 生成语法分析器实例
parser = yacc.yacc()

4. 测试解析效果

把你给出的示例代码喂给解析器,验证结果:

test_code = '''
on create:
  modifyProp relative width => 11
  modifyProp height => 14
'''

# 解析并打印AST
result = parser.parse(test_code)
import json
print(json.dumps(result, indent=2))

运行后会输出结构化的AST:

[
  {
    "type": "event_handler",
    "event": "create",
    "actions": [
      {
        "type": "modify_property",
        "relative": true,
        "property": "width",
        "value": 11
      },
      {
        "type": "modify_property",
        "relative": false,
        "property": "height",
        "value": 14
      }
    ]
  }
]

补充说明

  • 缩进处理:上面的示例没有严格实现Python式的缩进敏感检查,如果需要强制要求缩进匹配,可以参考PLY官方文档的缩进处理方案,通过维护缩进栈生成INDENT和DEDENT Token来实现。
  • 扩展逻辑:如果后续要加新关键字或语法,直接在词法分析器加Token、语法分析器加规则即可。
  • 语义执行:可以修改语法规则里的语义动作,比如直接生成可执行的Python代码,而不是AST结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:22:53