2014-11-01 87 views
1

我有一个语法:为什么我的语法被突变?

#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)))) 

mgotoalpha将交换@alpha在状态每个生产IFF @立即alpha之前。当我在状态结构上执行这个操作时,原始语法中的生产也会发生变化,以反映我以mgoto形式做出的更改。

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

注:closure,在gr说法是从一个电话传递给

(copy-Grammar) 

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

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

编辑:

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

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

当我印刷原始语法和修改后的状态下,两种结构进行了修改。

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

回答

1

我想你的copy-production只做一个浅拷贝,我。即它复制production的顶层结构,但里面的sentential被复制为引用。

+0

我认为可能会出现的情况,但如果你 '(SETF(生产句型(第一(国家制作的任何状态))) (推#\ R(生产句型(第一( State-Productions any-state))))' 然后只修改状态,语法不变 – myselfesteem 2014-11-01 20:38:29

+0

我最终接受了您的建议并实施了自己的深层复制 – myselfesteem 2014-11-01 21:50:29

相关问题