Python 创建声明性迷你语言
2007-03-30 12:31:54 来源:WEB开发网核心提示: 清单 7. basic_lex.pydef lex():for t in tokens:print t, '=', globals()[t]这会产生:% python basic_app.pyALPHANUMS = [a-zA-Z0-0]+WORDPUNCT = [-_]C
清单 7. basic_lex.py
def lex():
for t in tokens:
print t, '=', globals()[t]
这会产生:
% python basic_app.py
ALPHANUMS = [a-zA-Z0-0]+
WORDPUNCT = [-_]
CONTRACTION = '(clock|d|ll|m|re|s|t|ve)
PLY 设法使用堆栈帧信息插入了导入模块的名称空间。例如:
清单 8. magic_lex.py
import sys
try: raise RuntimeError
except RuntimeError:
e,b,t = sys.exc_info()
caller_dict = t.tb_frame.f_back.f_globals
def lex():
for t in caller_dict['tokens']:
print t, '=', caller_dict['t_'+t]
这产生了与 basic_app.py 样本所给输出一样的输出,但是具有使用前面 t_TOKEN 样式的声明。
实际的 PLY 模块中要比这更神奇。我们看到用模式 t_TOKEN 命名的标记实际上可以是包含了正则表达式的字符串,或是包含了正则表达式文档字符串和操作代码的函数。某些类型检查允许以下多态行为:
清单 9. polymorphic_lex
# ...determine caller_dict using RuntimeError...
from types import *
def lex():
for t in caller_dict['tokens']:
t_obj = caller_dict['t_'+t]
if type(t_obj) is FunctionType:
print t, '=', t_obj.__doc__
else:
print t, '=', t_obj
显然,相对于用来玩玩的示例而言,真正的 PLY 模块用这些已声明的模式可以做更有趣的事,但是这些示例演示了其中所涉及的一些技术。
更多精彩
赞助商链接