4 1 3 直譯器的資料結構

2021-08-24 20:59:49 字數 4579 閱讀 8055

4.1.3 直譯器的資料結構

除了定義表示式的外部語法,直譯器的實現必須定義其內部操作的資料結構,

作為乙個程式執行的一部分,例如程式和環境的表示,真值與假值的表示。

* 斷言的測試

對於條件,我們接受任何事為真,如果它不是顯式地顯示為假的物件。

(define (true? x)

(not (eq? x false)))

(define (false? x)

(eq? x false))

* 表示程式

為了處理原生的程式,我們假定已經有如下的程式可用了。

(primitive-procedure? )

測試是否是乙個原生的程式。

對於處理原生程式的這些機制,在4.1.4部分中有進一步的描述。

復合程式是由引數,程式體和環境變數這三個部分,使用組裝子make-procedure組裝而成。

(define (make-procedure parameters body env)

(list 'procedure parameters body env))

(define (compound-procedure? p)

(tagged-list? p 'procedure))

(define (procedure-parameters p) (cadr p))

(define (procedure-body p) (caddr p))

(define (procedure-environment p) (cadddr p))

* 對環境的操作

直譯器需要操作環境的操作。正如在3.2部分中的解釋,乙個環境是

乙個幀的序列,任何乙個幀都是乙個繫結了相關的變數和它們的相應的值的**。

我們使用操作環境的如下的操作:

(lookup-variable-value )

返回在環境中的符號繫結的值,如果變數沒有繫結,返回乙個錯誤。

(extend-environment )

返回乙個新的環境,它由乙個新的幀組成,在列表中的符號被繫結

到列表中的相應的元素上,它的父級環境是環境。

(define-variable! )

在環境的第乙個幀中加上乙個新的繫結,它是變數與值的繫結。

(set-variable-value! )

在環境中改變變數的繫結,所以變數現在的繫結的值是,

如果變數沒有繫結,返回乙個錯誤。

為了實現這些操作,我們把乙個環境表示為乙個幀的列表。乙個環境的父級環境是列表的

cdr部分。空的環境是乙個簡單的空列表。

(define (enclosing-environmen env) (cdr env))

(define (first-frame env) (car env))

(define the-empty-environment '())

乙個環境的任何乙個幀被表示為乙個列表的數對:在幀中,乙個變數的列表繫結到

相應的值的列表上。

(define (make-frame variables values) (cons variables values))

(define (frame-variables frame) (car frame))

(define (frame-values frame) (cdr frame))

(define (add-binding-to-frame! var val frame)

(set-car! frame (cons var (car frame)))

(set-cdr! frame (cons val (cdr frame))))

為了擴充套件乙個環境,通過乙個新的幀把變數和值關聯,我們做乙個幀

由變數的列表和值的列表組成,我們把這關聯到環境.如果變數的數量

沒有匹配值的數量,我們報乙個錯誤.

(define (extend-environment vars vals base-env)

(if (= (length vars) (length vals))

(cons (make-frame vars vals) base-env)

(if (< (length vars) (length vals))

(error "too many arugments supplied" vars vals)

(error "too few arguments supplied" vars vals)))

)為了在環境中查詢乙個變數,我們在第乙個幀中掃瞄變數的列表。如果我們發現了

期望的變數,我們返回值的列表中的相應的元素。如果我們沒有找到當前的幀中的

變數,我們搜尋父級環境等等。如果我們到達了空的環境,我們發乙個沒有繫結變數

的報錯。

(define (lookup-variable-value var env)

(define (env-loop env)

(define (scan vars vals)

(cond ((null? vars) (env-loop (enclosing-environment env)))

((eq? var (car vars))

(car vals))

(else (scan (cdr vars) (cdr vals)))

))(if (eq? env the-empty-environment)

(error "unbound variable" var)

(let ((frame (first-frame env)))

(scan (frame-variables frame)

(frame-values frame))))

) (env-loop env))

在乙個特定的環境中,為了把變數設定成乙個新的值,我們掃瞄變數,正如

在lookup-variable-value做的那樣。當我們找到它的時候,修改相應的值。

(define (set-variable-value! var val env)

(define (env-loop env)

(define (scan vars vals)

(cond ((null? vars) (env-loop (enclosing-environment env)))

((eq? var (car vars))

(set-car! vals val))

(else (scan (cdr vars) (cdr vals)))

))(if (eq? env the-empty-environment)

(error "unbound variable --set" var)

(let ((frame (first-frame env)))

(scan (frame-variables frame)

(frame-values frame))))

) (env-loop env))

為了定義乙個變數,我們搜尋為了變數的繫結的第乙個幀,如果它存在,

就改變繫結(正如在set-variable-value!).如果沒有這個繫結存在,

我們把它加到第乙個幀。

(define (define-variable! var val env)

(let ((frame (first-frame env)))

(define (scan vars vals)

(cond ((null? vars)

(add-binding-to-frame! var val frame))

((eq? var (car vars))

(set-car! vals val))

(else (scan (cdr vars) (cdr vals)))

))(scan (frame-variables frame)

(frame-values frame))))

這裡描述的方法僅是表示環境的所有的可能的方式之一。

因為我們使用的資料抽象來隔離直譯器的其它部分與表示

的細節性的選擇,如果我們需要,我們能選擇環境的表示法。

(見練習4.11)在乙個產品級的lisp系統中,直譯器的環境

操作速度,特別是變數的查詢,對系統的效能有重大的影響。

這裡描述的表示法,儘管概念上是簡單的,但是在乙個產品

系統中它沒有效率的也沒有被普遍使用。

練習4.11

代替表示乙個幀為乙個列表的數對,我們能表示乙個幀作為繫結的列表,

任何乙個繫結是乙個名稱和值的數對.使用這個新的表示,重寫環境操作.

練習4.12

為了遍歷環境結構,程式set-variable-value! ,define-variable! 和

lookup-variable-value能被表達使用更抽象的程式。定義抽象來捕獲共同的模式,

重定義這些抽象的這三個程式。

練習4.13

scheme通過使用define方法允許我們建立變數的新的繫結,但是沒有提供處理

繫結的方式。實現直譯器的make-unbound!的內部程式,當make-unbound!表示式

被解釋時從環境中把乙個給定的符號的繫結刪除。這個問題沒有完整的被指定。

例如,我們應該僅移除環境的第一幀中的繫結嗎?完成規範和調整你做的選擇。

資料結構 魔王語言解釋

一 需求分析 1 有乙個魔王總是使用自己的一種非常精煉而抽象的語言講話,沒有人能聽得懂,但他的語言是可以逐步解釋 能聽懂的語言,因為他的語言是由以下兩種形式的規則由人的語言逐步抽象上去的 1 1 2 m 2 1 2 n n n 1 1 在這兩種形式中,從左到右均表示解釋。試寫乙個魔王語言的解釋系統,...

資料結構 名詞解釋

1 資料集合中各個資料元素之間的邏輯關係,即資料的邏輯結構 2 在對資料進行處理時,各資料元素在計算機中的儲存關係,即資料的儲存結構 3 對各種資料結構進行的運算。資料結構 是指相互有關聯的資料元素的集合。在具有相同特徵的資料元素集合中,各個資料元素之間存在有某種關係,這種關係反映了該集合中的資料元...

資料結構迷宮問題 快速迭代器生成的資料結構

c 輸入輸出 string的簡單使用 陣列和向量 對角線問題 陣列和向量的排序 二分查詢原理 陣列二分查詢 向量二分查詢 3n 1問題 抽象資料型別 查詢問題的抽象資料型別視角 初識集合 次序統計量 有序向量與無序向量 以集合描述演算法 stl容器一覽 時空之謎 程式執行時間 量級常見執行時間 執行...