我将在Python中实现一个tokenizer,我想知道你是否可以提供一些样式建议?
我之前在C和Java中实现了一个标记化器,所以我对理论很好,我只想确保我遵循pythonic样式和最佳实践.
列出令牌类型:
例如,在Java中,我会有一个像这样的字段列表:
public static final int TOKEN_INTEGER = 0
但是,显然,我没有办法(我认为)在Python中声明一个常量变量,所以我可以用普通的变量声明替换它,但这并没有让我成为一个很好的解决方案,因为声明可能会被改变.
从Tokenizer返回令牌:
有没有更好的替代方案,只需返回一个元组列表,例如
[ (TOKEN_INTEGER, 17), (TOKEN_STRING, "Sixteen")]?
干杯,
皮特
re
模块中有一个未记录的类叫做re.Scanner
.使用标记器非常简单:
import re scanner=re.Scanner([ (r"[0-9]+", lambda scanner,token:("INTEGER", token)), (r"[a-z_]+", lambda scanner,token:("IDENTIFIER", token)), (r"[,.]+", lambda scanner,token:("PUNCTUATION", token)), (r"\s+", None), # None == skip token. ]) results, remainder=scanner.scan("45 pigeons, 23 cows, 11 spiders.") print results
会导致
[('INTEGER', '45'), ('IDENTIFIER', 'pigeons'), ('PUNCTUATION', ','), ('INTEGER', '23'), ('IDENTIFIER', 'cows'), ('PUNCTUATION', ','), ('INTEGER', '11'), ('IDENTIFIER', 'spiders'), ('PUNCTUATION', '.')]
我用re.Scanner编写了一个非常好的配置/结构化数据格式解析器,只有几百行.
Python采取了"我们都同意成人"的信息隐藏方法.可以使用变量就像它们是常量一样,并且相信代码的用户不会做一些愚蠢的事情.
在许多情况下,exp.在解析长输入流时,您可能会发现将tokenizer实现为生成器函数更有用.这样,您可以轻松地遍历所有令牌,而无需大量内存来构建令牌列表.
对于生成器,请参阅原始提案或其他在线文档
感谢您的帮助,我已经开始将这些想法融合在一起,并且我已经提出了以下建议.这个实现有什么特别的错误(特别是我担心将文件对象传递给tokenizer):
class Tokenizer(object): def __init__(self,file): self.file = file def __get_next_character(self): return self.file.read(1) def __peek_next_character(self): character = self.file.read(1) self.file.seek(self.file.tell()-1,0) return character def __read_number(self): value = "" while self.__peek_next_character().isdigit(): value += self.__get_next_character() return value def next_token(self): character = self.__peek_next_character() if character.isdigit(): return self.__read_number()