在Python中实现可定制的Lexer类
我想实现一个可定制和可扩展的lexer类 我的想法 2种不同类型的处理程序: 字符集处理程序 函数处理程序 当一个字符被读取时,它会被推送到所有注册到lexer的处理程序中。一旦处理程序匹配并返回有效令牌,就会返回该令牌。当没有处理程序匹配该字符时,将调用最坏情况下的函数,如果该函数未返回有效标记,则将读取下一个字符并递归执行 字符集处理程序由一个字符串和一个带有三个参数的函数组成。该字符串表示一组字符,当当前解析的字符包含在该字符串中时,将导致调用该函数。当函数无法创建以下字符的标记时,它可能返回None。如果无法处理所有正在读取的字符,则函数必须将其推回,以便创建令牌。下一次调用scanner.read_next_char时,将返回推回到扫描仪的字符,这样可以读取输入的字节流,就像函数从未接触过扫描仪一样 函数处理程序是一个包含三个参数的函数,如果它无法创建一个有效的令牌,并且该令牌后面的字符是调用该处理程序的字符,则该函数将返回一个有效令牌或无,就像与上面的字符集相关联的函数一样 当没有处理程序能够从当前标记创建有效标记时,将调用最坏情况下的函数,该标记包含以下字符并遵循上述模式 每个处理程序都有三个参数,lexer本身、lexer用来读取以下字符的扫描器以及实际调用处理程序的当前字符 Lexer本身和处理程序是分开的在Python中实现可定制的Lexer类,python,parsing,lexical-analysis,Python,Parsing,Lexical Analysis,我想实现一个可定制和可扩展的lexer类 我的想法 2种不同类型的处理程序: 字符集处理程序 函数处理程序 当一个字符被读取时,它会被推送到所有注册到lexer的处理程序中。一旦处理程序匹配并返回有效令牌,就会返回该令牌。当没有处理程序匹配该字符时,将调用最坏情况下的函数,如果该函数未返回有效标记,则将读取下一个字符并递归执行 字符集处理程序由一个字符串和一个带有三个参数的函数组成。该字符串表示一组字符,当当前解析的字符包含在该字符串中时,将导致调用该函数。当函数无法创建以下字符的标记时,它可能
class LexingRules(object):
def __init__(self):
self.charset_handlers = []
self.function_handlers = []
self.worst_case = None
# convenient methods for adding handlers
class Lexer(object):
def __init__(self, scanner, rules):
self.scanner = scanner
self.rules = rules
self.current_token = None
self.read_next_token()
def read_next_token(self):
current_char = self.scanner.current_char
for charset, handler in self.rules.charset_handlers:
if current_char in charset:
token = handler(self, self.scanner, current_char)
if isinstance(token, Token):
self.current_token = token
return token
for function in self.rules.function_handlers:
token = function(self, self.scanner, current_char)
if isinstance(token, Token):
self.current_token = token
return token
if self.rules.worst_case:
token = self.rules.worst_case(self, self.scanner, current_char)
if isinstance(token, Token):
self.current_token = token
return token
self.scanner.read()
return self.read_next_token()
一个可能的LexingRules子类
目的
基本Lexer实现和硬编码Lexing操作的分离
我目前正处于我自己项目的开始阶段。我想创建一种可扩展的编译/翻译语言。应该可以创建语法和语句扩展等
问题
您对lexer的设计有何看法?您是否有什么可抱怨的,或者有什么想法可以改进它,增加更多功能?这看起来像是大规模的过度工程。。。你想做什么?只是添加了一个小的编辑,基本Lexer实现和硬编码Lexing操作的分离。。我的新语言的语言扩展应该不仅能够创建新语句,甚至实现新类型的标记,因此语法将被扩展解析并转换为AST。@delnan忘记了@stuff..@NiklasR:1从不在注释中添加关键事实。你的目标应该是第一个,而不是最后一个。然后,您可以删除这两个无用的注释,因为它们现在被放在您的问题的显著位置。2您熟悉哪些现有的Python lexer?你应该在你的问题中提到它们。帘布层相当好,目前尚不清楚这如何可能改善帘布层。
import string
class MyLexingRules(LexingRules):
def __init__(self):
super(MyLexingRules, self).__init__()
self.charset_handlers.append(string.ascii_letters, self.handle_letters)
def handle_letters(self, lexer, scanner, char):
tkn = ''
while scanner.current_char in string.ascii_letters:
tkn += scanner.current_char
scanner.read()
return Token(tkn, TOKEN_ID_IDENTIFIER)