如何让SBCL中read-from-string正确识别上标²且不修改原字符串?
解决SBCL中read-from-string无法正确识别上标²的问题
SBCL默认会将Unicode上标²这类字符映射为普通数字2,导致read-from-string解析时丢失原字符信息。要在不修改原字符串的前提下解决这个问题,可通过调整Reader的语法配置实现:
全局修改Reader语法(永久生效)
直接修改上标字符的语法属性,让Reader将其视为符号的组成部分而非等价映射:;; 清除上标²原有的映射关系 (set-syntax-from-char #\² #\²) ;; 设置该字符为符号 constituent(与字母语法类型一致) (set-syntax-type #\² :constituent)执行后再运行你的代码:
(let ((code "(defun ² (x) (* x x))")) (second (read-from-string code)))会得到符号
²而非|2|,"x²"与"x2"也会被解析为不同内容。局部修改Reader语法(仅代码块内生效)
若不想全局改变Reader行为,可借助with-standard-io-syntax做局部配置:(with-standard-io-syntax (set-syntax-from-char #\² #\²) (set-syntax-type #\² :constituent) (let ((code "(defun ² (x) (* x x))")) (print (second (read-from-string code)))))
原理:SBCL的Reader默认对部分Unicode字符做等价ASCII映射(如上标数字转普通数字),通过set-syntax-from-char清除原有映射、set-syntax-type定义字符为符号组成部分,就能让Reader保留原字符的语义。
内容的提问来源于stack exchange,提问作者Fnifni
相关产品推荐
相关产品推荐

