You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需手动遍历检查,如何实现自定义编程语言的词法分析器?

自定义词法分析器的优化方案(避免大量if/else)

用正则表达式是替代手动遍历+大量if/else的绝佳方案,你可以把所有Token的匹配规则集中定义成一个列表,每个规则包含正则模式和对应的Token类型,然后通过正则引擎一次性匹配所有可能的token,彻底消除分支嵌套问题。

下面是修改后的实现代码:

import re

class Token:
    def __init__(self, type, value):
        self.type = type
        self.value = value

    def __str__(self):
        return f'Token({self.type}, {self.value})'

    def __repr__(self):
        return self.__str__()

# 定义所有Token规则,注意顺序:优先匹配更长/更特殊的规则(比如关键词要在标识符前面)
TOKEN_RULES = [
    # 关键词
    (r'if', 'KEYWORD_IF'),
    (r'else', 'KEYWORD_ELSE'),
    (r'while', 'KEYWORD_WHILE'),
    (r'return', 'KEYWORD_RETURN'),
    # 标识符(字母开头,字母数字下划线)
    (r'[a-zA-Z_][a-zA-Z0-9_]*', 'IDENTIFIER'),
    # 数字(整数和浮点数)
    (r'\d+\.\d+', 'FLOAT'),
    (r'\d+', 'INTEGER'),
    # 运算符和分隔符
    (r'\+', 'OP_ADD'),
    (r'-', 'OP_SUB'),
    (r'\*', 'OP_MUL'),
    (r'/', 'OP_DIV'),
    (r'=', 'OP_ASSIGN'),
    (r'\(', 'PAREN_OPEN'),
    (r'\)', 'PAREN_CLOSE'),
    (r'{', 'BRACE_OPEN'),
    (r'}', 'BRACE_CLOSE'),
    (r';', 'SEMICOLON'),
    # 空白字符(忽略)
    (r'\s+', None),
]

# 编译正则表达式,用|连接所有模式,添加命名分组便于识别Token类型
pattern = re.compile('|'.join(f'(?P<{token_type}>{regex})' for regex, token_type in TOKEN_RULES if token_type is not None))

def lex(code):
    tokens = []
    # 遍历所有匹配结果,自动处理位置偏移
    for match in pattern.finditer(code):
        token_type = match.lastgroup
        token_value = match.group()
        tokens.append(Token(token_type, token_value))
    return tokens

关键说明:

  • 规则顺序优先级:比如if这类关键词必须放在IDENTIFIER规则前面,否则正则会把if识别成普通标识符。
  • 忽略无关Token:像空格这类不需要保留的Token,可将类型设为None,编译时自动跳过。
  • 预编译提升性能:提前编译正则表达式能避免重复解析,大幅提升多次调用lex函数时的效率。
  • 自动位置管理:finditer会自动从上次匹配结束的位置继续扫描,不需要手动维护索引变量,彻底替代手动遍历逻辑。

你可以根据自定义语言的语法需求,随时扩展或修改TOKEN_RULES,比如添加字符串、注释的匹配规则,这种方式比手写大量if/else更易维护,性能也更稳定。

内容的提问来源于stack exchange,提问作者BrandonDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 19:35:22