如何使用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和DEDENTToken来实现。 - 扩展逻辑:如果后续要加新关键字或语法,直接在词法分析器加Token、语法分析器加规则即可。
- 语义执行:可以修改语法规则里的语义动作,比如直接生成可执行的Python代码,而不是AST结构。
内容的提问来源于stack exchange,提问作者Vixey
相关产品推荐
相关产品推荐

