2014-11-01 84 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

相關問題