Functional programming 为什么我的语法发生了变异?

Functional programming 为什么我的语法发生了变异?,functional-programming,lisp,common-lisp,Functional Programming,Lisp,Common Lisp,我有一个语法: #S(GRAMMAR :START ' :SYMBOLS (i ) ( F * T + E) :NONTS (F T E') :PRODUCTIONS (#S(PRODUCTION :NONT ' :SENTENTIAL (@ E)) #S(PRODUCTION :NONT E :SENTENTIAL (@ E + T)) #S(PRODUCTION :NONT E :SENTENTIAL (@ T))

我有一个语法:

#S(GRAMMAR

:START '

:SYMBOLS (i ) ( F * T + E)

:NONTS (F T E')

:PRODUCTIONS (#S(PRODUCTION :NONT ' :SENTENTIAL (@ E))
              #S(PRODUCTION :NONT E :SENTENTIAL (@ E + T))
              #S(PRODUCTION :NONT E :SENTENTIAL (@ T))
              #S(PRODUCTION :NONT T :SENTENTIAL (@ T * F))
              #S(PRODUCTION :NONT T :SENTENTIAL (@ F))
              #S(PRODUCTION :NONT F :SENTENTIAL (@ ( E )))
              #S(PRODUCTION :NONT F :SENTENTIAL (@ i))))
这个功能是:

(defun mgoto (s sym)
  (princ "Computing GOTO on: ")
  (princ sym)
  (princ #\Newline)
  (let ((result '())
        (st (copy-State s)))
    (map '()
         #'(lambda (x)
             (let ((dot (position sym (Production-sentential x))))
               (when (not (null dot))
                 (setq dot (1- dot))
                 (when (and (>= dot 0)
                            (char= #\@
                                   (nth dot (Production-sentential x))))
                   (let ((copy (copy-Production x)))
                     (rotatef (nth dot      (Production-sentential copy))
                              (nth (1+ dot) (Production-sentential copy)))
                     (format t "~A~%~%" copy)
                     (push copy result))))))
         (State-productions st))
    (make-state :name (list 'I (incf *COUNT*)) :productions result)))
它接受一个状态和一个语法符号。初始状态如下所示:

#S(STATE
    :NAME (I 0) 
    :PRODUCTIONS (#S(PRODUCTION :NONT ' :SENTENTIAL (@ E))
                  #S(PRODUCTION :NONT E :SENTENTIAL (@ T))
                  #S(PRODUCTION :NONT E :SENTENTIAL (@ E + T))
                  #S(PRODUCTION :NONT T :SENTENTIAL (@ F))
                  #S(PRODUCTION :NONT T :SENTENTIAL (@ T * F))
                  #S(PRODUCTION :NONT F :SENTENTIAL (@ I))
                  #S(PRODUCTION :NONT F :SENTENTIAL (@ ( E )))))
并由以下内容生成:

(defun closure (g-prod gr)
  (let ((j (list (copy-Production (first g-prod))))
        (len0 0)
        (grammar gr))
    (loop do
          (setq len0 (length j))
          (map '()
               #'(lambda (jprod)
                   (map '()
                        #'(lambda (prod2)
                            (if (not (member prod2 j :test 'tree-equal))
                                (setq j (append j (list prod2)))))
                        (get-productions
                         (1+ (position #\@ (Production-sentential jprod)))
                         (Production-sentential jprod) grammar)))
               j)
          until (= (length j) len0))
    (list (make-State :name (list 'I (incf *COUNT*)) :productions j))))
mgoto
上的
alpha
将在
alpha
之前的
@
状态下为每个生产交换
@
。当我对状态结构执行此操作时,原始语法中的结果也会更改,以反映我在mgoto中所做的更改

我试图尽可能多地复制我的结构,以保持原始语法的完整性,但尽管如此,当我计算goto时,我的语法总是被修改

注意:
closure
中,
gr
参数是从对的调用传入的

(copy-Grammar)
参考:我正在计算自下而上解析器的LR(0)项集:

你对我做得不对有什么建议吗

编辑:

我想问题出在打电话给mgoto的rotatef。 测试用例:

(rotatef (nth 0 (Production-Sentential (first (State-Productions any-state)))
         (nth 1 (Production-Sentential (first (State-Productions any-state))))
当我打印原始语法和修改状态时,这两种结构都被修改了


有没有办法让
rotatef
只修改状态结构?

我想你的
复制产品只做浅拷贝,即。E它复制了
产品的顶层结构,但是里面的
语句作为参考被复制。

我想可能是这样的,但是如果你这样做了
(setf(生产语句(第一(状态生产任何状态)))(push#\r(生产语句(第一(状态生产任何状态)))
然后只有状态被修改,语法被保留,我最终接受了你的建议,实现了我自己的深度复制