常见的 lisp 和中缀包
Common lisp and infix package
有common lisp的中缀包(见http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/syntax/infix/infix.cl),将中缀形式转换为前缀。
例如:
(string->prefix "1+2") ;; => (+ 1 2)
它还提供了reader宏#I,它可以评估中缀形式,例如
#I(1+2) ;; => 3
但我不想使用这个 reader 宏。
我写了一个简单的函数,它使用 cl-ppcre 来用数字替换字符串,即
(prepare-form "1+x*x" "x" 3) ;; => "1+3*3"
最后,我有一个计算中缀形式的函数
(defun eval-infix (form &rest args)
(eval (string->prefix (apply #'prepare-form form args))))
eval-infix函数可以不使用eval函数实现吗?
我的最终目标是像这样调用 eval-infix:
(eval-infix "1+x*x" "x" (+ 1 2))
嗯,我想你想用的是string->prefix
。这将实习生符号,以避免污染您自己的包让我们定义一个。最后,您可以通过定义自己的 eval 来避免 eval 的安全问题。仍然存在可以写入其他包中的符号的问题,这让我很难过。还有一个问题是中缀 reader 可以逃逸到可以进行任意计算的 Lisp reader 。这是解决方案各部分的草图。我可能以错误的顺序获得了某些函数的参数。
(defpackage infix-vars)
(defun read-infix-string (s) (let ((*package* (find-package "INFIX-VARS"))) (string->prefix s)))
(defun substitute-var (expr v val)
(let ((v (etypecase v (symbol v) (string (intern v (find-package "INFIX-VARS"))))))
(subst expr v val)))
(defun eval-expr (e)
(etypecase e
(number e)
(list
(ecase (car e)
(+ (apply #'+ (mapcar #'eval-expr (cdr e))))))))
有common lisp的中缀包(见http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/syntax/infix/infix.cl),将中缀形式转换为前缀。
例如:
(string->prefix "1+2") ;; => (+ 1 2)
它还提供了reader宏#I,它可以评估中缀形式,例如
#I(1+2) ;; => 3
但我不想使用这个 reader 宏。
我写了一个简单的函数,它使用 cl-ppcre 来用数字替换字符串,即
(prepare-form "1+x*x" "x" 3) ;; => "1+3*3"
最后,我有一个计算中缀形式的函数
(defun eval-infix (form &rest args)
(eval (string->prefix (apply #'prepare-form form args))))
eval-infix函数可以不使用eval函数实现吗? 我的最终目标是像这样调用 eval-infix:
(eval-infix "1+x*x" "x" (+ 1 2))
嗯,我想你想用的是string->prefix
。这将实习生符号,以避免污染您自己的包让我们定义一个。最后,您可以通过定义自己的 eval 来避免 eval 的安全问题。仍然存在可以写入其他包中的符号的问题,这让我很难过。还有一个问题是中缀 reader 可以逃逸到可以进行任意计算的 Lisp reader 。这是解决方案各部分的草图。我可能以错误的顺序获得了某些函数的参数。
(defpackage infix-vars)
(defun read-infix-string (s) (let ((*package* (find-package "INFIX-VARS"))) (string->prefix s)))
(defun substitute-var (expr v val)
(let ((v (etypecase v (symbol v) (string (intern v (find-package "INFIX-VARS"))))))
(subst expr v val)))
(defun eval-expr (e)
(etypecase e
(number e)
(list
(ecase (car e)
(+ (apply #'+ (mapcar #'eval-expr (cdr e))))))))