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

基于Python实现Lisp方言的词法分析方案求助

实现极简Lisp方言的纯函数式词法分析器

我对Lisp语言感兴趣,想做一款极简Lisp方言——这个方言里所有内容都是列表,列表以命令开头,参数也能是列表。为此我定义了如下KList类:

class KList:
    def __init__(self, command, args=None):
        self.command = command
        self.args = args

现在需要把(+ 1 2)这类Lisp表达式转换成KList('+', [KList('1'), KList('2')])的结构,同时得满足两个要求:

  • 不依赖任何词法分析库
  • 用纯函数式Python实现,不能有语句和变量突变

纯函数式实现方案

1. 词法分析(Tokenize)

先把输入的表达式字符串拆分成可处理的token,全程用递归和列表拼接,避免变量修改:

def tokenize(s):
    def helper(s, tokens):
        if not s:
            return tokens
        c = s[0]
        if c in '()':
            return helper(s[1:], tokens + [c])
        elif c.isspace():
            return helper(s[1:], tokens)
        else:
            # 提取连续的非空格、非括号字符作为原子token
            end = 1
            while end < len(s) and not s[end].isspace() and s[end] not in '()':
                end += 1
            return helper(s[end:], tokens + [s[:end]])
    return helper(s, [])

2. 语法解析(Parse)

把token列表转换成KList结构,同样用递归实现,无变量突变:

def parse(tokens):
    def helper(tokens):
        if not tokens:
            raise ValueError("输入意外结束")
        token = tokens[0]
        if token == '(':
            # 递归解析列表内的参数
            def parse_args(tokens, args):
                if not tokens:
                    raise ValueError("未闭合的括号")
                if tokens[0] == ')':
                    return args, tokens[1:]
                arg, rest = helper(tokens)
                return parse_args(rest, args + [arg])
            args, rest = parse_args(tokens[1:], [])
            if not args:
                raise ValueError("不允许空列表")
            # 第一个参数作为命令,剩下的作为参数列表
            cmd = args[0].command if isinstance(args[0], KList) else args[0]
            return KList(cmd, args[1:]), rest
        elif token == ')':
            raise ValueError("意外的右括号")
        else:
            # 原子项直接转为无参数的KList
            return KList(token), tokens[1:]
    result, rest = helper(tokens)
    if rest:
        raise ValueError(f"意外的token: {rest}")
    return result

使用示例

# 测试基础表达式(+ 1 2)
expr = "(+ 1 2)"
tokens = tokenize(expr)
klist = parse(tokens)
print(klist.command)  # 输出: '+'
print([arg.command for arg in klist.args])  # 输出: ['1', '2']

# 测试嵌套表达式(* (+ 3 4) 5)
expr2 = "(* (+ 3 4) 5)"
klist2 = parse(tokenize(expr2))
print(klist2.command)  # 输出: '*'
print(klist2.args[0].command)  # 输出: '+'
print([arg.command for arg in klist2.args[0].args])  # 输出: ['3', '4']
print(klist2.args[1].command)  # 输出: '5'

实现说明

  • tokenize通过递归遍历字符串,把字符拆分为括号、原子符号等token,全程用列表拼接而非修改已有变量,符合纯函数式要求。
  • parse递归处理token列表,遇到左括号就解析内部参数,组装成KList;原子项直接转为无参数的KList,全程没有变量赋值修改。
  • 整个实现没有依赖任何第三方库,只用了Python内置的字符串和列表操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:25:21