Python实现Lisp方言解析函数时的字符串处理问题
问题分析
原实现的核心问题在于用全局替换和shlex拆分的方式处理结构化表达式,无法区分字符串内部和外部的语法元素,导致字符串内的括号被错误处理、引号丢失,转义引号直接引发解析崩溃。
解决方案
我们需要实现一个带状态的迭代解析器,精准区分字符串上下文和普通表达式上下文,处理转义字符,同时保留字符串的原始引号。以下是修复后的实现:
def parse_lisp_expr(expr): tokens = [] current_token = [] in_string = False escaped = False for char in expr: if escaped: current_token.append(char) escaped = False continue if char == '\\': escaped = True current_token.append(char) continue if char == '"': current_token.append(char) in_string = not in_string # 字符串结束时,将完整字符串作为一个token存入 if not in_string: tokens.append(''.join(current_token)) current_token = [] continue if in_string: current_token.append(char) continue # 非字符串上下文,处理括号和空白分隔的token if char in '()': if current_token: tokens.append(''.join(current_token)) current_token = [] tokens.append(char) elif char.isspace(): if current_token: tokens.append(''.join(current_token)) current_token = [] else: current_token.append(char) # 处理最后一个未结束的token if current_token: tokens.append(''.join(current_token)) # 用栈构建嵌套元组结构 stack = [] current_list = [] for token in tokens: if token == '(': stack.append(current_list) current_list = [] elif token == ')': if not stack: raise SyntaxError("Mismatched parentheses") stack[-1].append(tuple(current_list)) current_list = stack.pop() else: current_list.append(token) if stack: raise SyntaxError("Mismatched parentheses") return current_list[0] if current_list else ()
修复效果验证
- 字符串内括号处理:输入
(println "Hello (world)"),输出('println', '"Hello (world)"'),字符串内的括号被完整保留。 - 保留字符串引号:输入
(println "Hello, world!"),输出('println', '"Hello, world!"'),完全符合预期格式。 - 转义引号处理:输入
(println "He said \"Hello!\""),输出('println', '"He said \\"Hello!\\""'),转义引号被正确解析并保留。
代码说明
- 状态机token拆分:通过
in_string和escaped两个状态变量,精准识别字符串边界和转义字符,确保字符串内部的所有字符(包括括号、转义符)都被完整保留为一个独立token。 - 栈结构构建嵌套元组:用栈处理Lisp的嵌套结构,遇到
(时保存当前上下文,遇到)时将当前列表转为元组并入上层结构,最终生成符合要求的嵌套元组。
内容的提问来源于stack exchange,提问作者KianFakheriAghdam
相关产品推荐
相关产品推荐

