Python中的词法分析:lex()函数与语法分析器的协作应用
发布时间:2023-12-25 18:40:05
词法分析是编译器中的一个重要步骤,它的作用是将源代码拆分成一个个的“单词”,也称为“词法单元”或“记号”,然后将这些单词传递给语法分析器进行进一步处理。词法分析器通常使用正则表达式来定义每个记号的模式,然后从源代码中匹配这些模式。
在Python中,我们可以使用ply库(Python Lex-Yacc)来进行词法分析和语法分析。ply库提供了lex()和yacc()函数来实现词法分析器和语法分析器的协作。
首先,我们需要定义记号的模式。假设我们要解析一个简单的算术表达式,包括加法、减法、乘法、除法和数字。我们可以定义如下的模式:
# 定义记号的模式
tokens = (
'NUMBER',
'PLUS',
'MINUS',
'TIMES',
'DIVIDE',
)
# 定义记号的具体规则
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
# 数字的规则,可以是整数或小数
def t_NUMBER(t):
r'\d+(\.\d+)?'
t.value = float(t.value) if '.' in t.value else int(t.value)
return t
# 忽略空格和换行符
t_ignore = '
'
接下来,我们可以使用ply库中的lex()函数创建词法分析器:
from ply import lex # 创建词法分析器 lexer = lex.lex()
创建词法分析器之后,我们可以使用lexer.input()方法将源代码传递给词法分析器,然后使用lexer.token()方法获取下一个记号:
# 将源代码传递给词法分析器
lexer.input('3 + 4 * 2')
# 获取下一个记号
token = lexer.token()
print(token)
输出结果为:
LexToken(NUMBER, 3, 1, 0)
这个记号表示数字3,在第1行第0列。
当我们想要获取所有的记号时,可以使用一个循环:
# 将源代码传递给词法分析器
lexer.input('3 + 4 * 2')
# 获取所有的记号
while True:
token = lexer.token()
if not token:
break
print(token)
输出结果为:
LexToken(NUMBER, 3, 1, 0) LexToken(PLUS, '+', 1, 2) LexToken(NUMBER, 4, 1, 4) LexToken(TIMES, '*', 1, 6) LexToken(NUMBER, 2, 1, 8)
这些记号分别表示数字3、加号、数字4、乘号和数字2。
注意:词法分析器使用的记号类型是一个特殊的类LexToken,它有四个属性:type(记号的类型)、value(记号的值)、lineno(记号在源代码中的行号)和lexpos(记号在源代码中的位置)。
