如何为简单表达式(如 expr = "res = 3 + x_sum*11")构建分词器



我们想为简单的表达式(如 xpr = "res = 3 + x_sum*11" (构建一个分词器。

此类表达式仅包含三个标记,如下所示:

(1( 整数文字:一个或多个数字,例如311;
(2( 标识符:以字母或下划线开头的字符串,后跟多个字母、数字或下划线,例如resx_sum;
(3(运营商=+*等。

应跳过前导或尾随空格字符。

要查找每个词素与哪个标记相关联,我们只需要找到每个元组中的第一个非空项。编写一个标记化生成器(使用 re.findallmap (,返回词素和标记的所有对(元组(。因此,list(tokenize(xpr))的输出应为:

[('res', 'id'), ('=', 'op'), ('3', 'int'), ('+', 'op'), ('x_sum', 'id'), ('*', 'op'), ('11', 'int')]
您可以使用

tokenize.tokenize

import tokenize
import token
import io
import collections
class Token(collections.namedtuple('Token', 'num val start end line')):
    @property
    def name(self):
        return token.tok_name[self.num]
    def __repr__(self):
        return '{} {!r} ({} {}): {!r}'.format(self.name, self.val,
                                              self.start, self.end, self.line)

line = b'res = 3 + x_sum*11'
result = [Token(*item) for item in tokenize.tokenize(io.BytesIO(line).readline)]
result = [(tok.val, tok.name) for tok in result[1:-1]]
print(result)

收益 率

[('res', 'NAME'), ('=', 'OP'), ('3', 'NUMBER'), ('+', 'OP'), ('x_sum', 'NAME'), ('*', 'OP'), ('11', 'NUMBER')]

您可以修改 Token.name 属性以完全匹配您的规范,但由于上面显示的令牌名称已在 token 模块中定义,因此您可能希望更改规范以匹配 Python 使用的名称(如果可以的话(。

最新更新