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

如何将命令行传入的S-expression字符串转为Python元组

如何将命令行传入的S-expression字符串转换为运算符元组

你的代码主要有两个问题导致解析失败:

  • Token分割错误:直接用split()会把(add、3)这类字符串当成单个token,没有把括号和内容分开,导致程序无法正确识别括号的位置。
  • 括号处理逻辑错误:遇到)时只固定弹出两个元素,这不符合S-expression的规则(运算符可以有多个参数),而且元组构造的顺序也不对。

正确实现步骤

  1. 先做正确的Token化:遍历输入字符串,把括号、运算符、数字拆分成独立的token,比如把"(add (multiply 2 3) 2)"拆成['(', 'add', '(', 'multiply', '2', '3', ')', '2', ')']。
  2. 用栈处理Token流:
    • 遇到(就压入栈,标记新表达式的开始。
    • 遇到数字或运算符直接压入栈。
    • 遇到)时,从栈中弹出元素,直到遇到对应的(,把弹出的元素(除了()反转后,第一个元素是运算符,后面是参数,组成元组压回栈。

完整代码实现

import sys

def tokenize(expression_str):
    tokens = []
    current = []
    for char in expression_str:
        if char in '()':
            if current:
                tokens.append(''.join(current))
                current = []
            tokens.append(char)
        elif char.isspace():
            if current:
                tokens.append(''.join(current))
                current = []
        else:
            current.append(char)
    if current:
        tokens.append(''.join(current))
    return tokens

def parse_sexp(tokens):
    stack = []
    for token in tokens:
        if token == '(':
            stack.append(token)
        elif token == ')':
            # 弹出元素直到左括号
            elements = []
            while stack[-1] != '(':
                elements.append(stack.pop())
            stack.pop()  # 弹出左括号
            # 反转元素,第一个是运算符,后面是参数
            elements.reverse()
            if not elements:
                raise ValueError("空表达式无效")
            operator = elements[0]
            args = elements[1:]
            # 把参数转成整数(如果是数字的话)
            parsed_args = []
            for arg in args:
                try:
                    parsed_args.append(int(arg))
                except ValueError:
                    parsed_args.append(arg)
            stack.append((operator, *parsed_args))
        else:
            stack.append(token)
    if len(stack) != 1:
        raise ValueError("表达式格式错误")
    return stack[0]

def from_expression_string(expression_string):
    tokens = tokenize(expression_string)
    return parse_sexp(tokens)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("用法: python calc.py \"(add (multiply 2 3) 2)\"")
        sys.exit(1)
    expr_str = sys.argv[1]
    result = from_expression_string(expr_str)
    print(result)

测试示例

运行命令:

python calc.py "(add (multiply 2 3) 2)"

输出结果:

('add', ('multiply', 2, 3), 2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:51:15