Common Lisp交互式用户输入程序编译报错求助
报错触发原因
- 第2行3列未定义变量
COMMON-LISP-USER::WORDS警告:Common Lisp遵循严格词法作用域规则,setq仅能给已显式声明的变量赋值,不会像Python那样直接通过赋值操作创建全局/局部变量。你未使用let/defvar声明words变量,直接对其赋值就会触发该警告。 - 第3行3列
LOOP宏展开报错:核心原因是括号配对完全混乱,整个代码块大量表达式位于loop宏的合法语法结构外,导致loop解析参数时直接失败。 - 额外隐藏语法错误(修正括号后仍会触发报错的问题):
- Common Lisp标准库不存在
string-include函数,属于自定义未实现的调用 read-delimited-list用于读取Lisp结构对象,而非用户输入的行字符串,且未指定输入流参数case语法使用完全错误:case需传入待匹配值,后续分支以(匹配键 执行体)结构编写,你将判断条件直接放在分支位置,不符合语法规范
- Common Lisp标准库不存在
修正后的可运行代码
;; 实现字符串包含判断的辅助函数 (defun string-contains (substr str) "判断str是否包含substr,大小写不敏感" (not (null (search substr str :test #'string-equal)))) (defun x () (let ((words "")) (loop while (string/= words "BYE") do (format t "ROBBIE%: 请输入内容:~%") ;; 读取一行用户输入,读取失败时默认返回BYE直接退出 (setq words (read-line *standard-input* nil "BYE")) ;; 空输入直接跳过本次循环 (when (string= words "") (loop-finish)) ;; 多条件分支匹配 (cond ((string-contains "I'm" words) (format t "ROBBIE%: Nice to see you, how are you?~%")) ((string-contains "Hi" words) (format t "ROBBIE%: How are you?~%")) ((or (string-contains "fine" words) (string-contains "person" words)) (format t "ROBBIE%: No I'm a computer~%")))) (format t "程序已退出~%")))
核心修改说明
- 使用
let在x函数内声明words局部变量,从根源解决未定义变量警告 - 补全所有缺失括号,补充
loop语法要求的do关键字,将循环体放在合法位置,解决宏展开报错 - 用
read-line替换错误的read-delimited-list,直接读取用户输入的整行字符串,适配交互场景 - 基于标准库
search实现string-contains,替代你不存在的string-include调用 - 用更适配多条件逻辑的
cond替换语法错误的case,实现关键词匹配分支 - 增加空输入、读取异常的兜底处理,避免程序崩溃
内容的提问来源于stack exchange,提问作者user12282981
相关产品推荐
相关产品推荐

