# pip install ply
基本例子
PLY 很魔法的一点是它使用到了模块内部反射. 也就是说在产生一个词法分析器时, 并不是把词法规则传递给 PLY 的接口, 而是依次将一些指定名字的变量或函数定义在 py 文件中.下面给出第一个例子, 从文本中抓出十进制数值.
import ply.lex
tokens = (
'NUMBER',
)
t_NUMBER = r'\d*[.]?\d+'
def t_error(t):
t.lexer.skip(1)
ply.lex.lex()
ply.lex.input('''
The Chinese mathematician Zu Chongzhi, around 480 AD, calculated that
pi ~= 355/113
(a fraction that goes by the name Milv in Chinese), using Liu Hui's
algorithm applied to a 12288-sided polygon. With a correct value for its
seven first decimal digits, this value of 3.141592920... remained the most
accurate approximation of pi available for the next 800 years.
<From Wikipedia:Pi>
''')
for token in iter(ply.lex.token, None):
print token.type, token.value
NUMBER 480
NUMBER 355
NUMBER 113
NUMBER 12288
NUMBER 3.141592920
NUMBER 800
- 文件中定义了
tokens
表示可能的词元类型; 在官方例子中, 其中的取值通常以全大写的形式出现 - 定义词元规则
t_NUMBER
, 其名字是token
变量中的成员'NUMBER'
加上前缀t_
; 在构造词法分析器时, PLY 会将以t_
开头的所有定义收集起来 - 词元规则
t_NUMBER
的取值是正则表达式, 用来匹配所有的数值 - 定义
t_error
函数, 如果什么奇怪的东西混进来, 这个函数会被调用; 不过现在只是抓取数值, 无视其它符号, 所以实现只是跳过一个字符 (skip
的参数是字符数量) - 调用
ply.lex.lex
构造词法分析器 - 调用
ply.lex.input
喂一些输入进去 - 从
ply.lex.token
获得词法分析的结果
利用分词输出
从这个基本例子迈向一个用于简单表达式计算的词法分析器并不困难. 如果按照之前一篇文章里所演示的那个功能 (请将该文章中最后一段代码保存在 expr_eval.py 中以供这次使用), 需要至少以下这些词元类型- 二元算符 */^
- 二元或一元算符 +-
- 括号
- 整数