为什么我的语法会发生变异?

时间:2014-11-01 16:14:57

标签: 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(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@交换状态iff alpha紧接closure之前的状态。当我在状态结构上执行此操作时,原始语法中的生成也会发生变化,以反映我在mgoto中所做的更改。

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

注意:gr中,(copy-Grammar) 参数从调用传入

(rotatef (nth 0 (Production-Sentential (first (State-Productions any-state)))
         (nth 1 (Production-Sentential (first (State-Productions any-state))))

参考:我正在为自下而上的解析器计算LR(0)项集: http://www.ittc.ku.edu/~kulkarni/teaching/EECS665/assignments/LR0Items/output.txt

你对我做错了什么有什么建议吗?

修改

在mgoto中调用rotatef我怀疑是问题。 测试用例:

rotatef

当我打印原始语法和修改后的状态时,两个结构都被修改了。

有没有办法让{{1}}只修改状态结构?

1 个答案:

答案 0 :(得分:1)

我猜你的copy-production只做一个浅色的副本,我。即它复制production的顶级结构,但内部的sentential被复制为引用。