REBOL(發音reb-ol ['reb-ol],英文Relative Expression Based Object Language的縮寫),自R3發行版改稱為Rebol[6],是跨平台的數據交換語言和多範式的動態程式語言。由AmigaOS的系統架構師Carl Sassenrath設計,用於網絡通訊和分散式計算。
簡介
REBOL介入了方言化的概念:用於代碼和數據的小型的、最佳化的領域特定語言[7][8],據設計者Carl Sassenrath所說這是這個語言最顯著的性質:「儘管它可以用於編程、寫函數和進行處理,它最大的長處是輕易的建立領域特定語言或方言的能力。[9]」
知名於JavaScript開發上貢獻的道格拉斯·克羅克福特,曾經描述Rebol為是對JSON有影響者之一:「更加現代的語言,但具有一些非常類似於Lisp的想法,它全部建造在數據表示之上,然後再被作為程式執行。[5]」
最初,這個語言和它的官方實現,是REBOL技術公司開發的專有和封閉原始碼的軟件。經過跟Lawrence Rosen的討論[10],Rebol版本R3直譯器於2012年12月12日在Apache 2.0許可證下發行[11]。老版本能以二進制形式獲得到,沒有發行它們的原始碼的規劃。
實例
Rebol的設計原理之一就是「以簡單方式做簡單的事情」[7]。使用下面的「可視介面方言」例子來描述一個具有圖形化使用者介面的簡單的Hello world程式:
view layout [text "Hello world!" button "Quit" [quit]]
使用R3-GUI的類似的例子:
view [text "Hello world!" button "Quit" on-action [quit]]
方言
Rebol的領域特定語言叫做「方言」,是為特定用途最佳化的微型語言。方言可以用來定義業務規則、圖形化使用者介面或在程式安裝期間的螢幕序列。用戶可以定義他們自己的方言,重用任何現存的Rebol單詞並給予它在方言中的特殊含義[7]。方言是有處理Robol塊的函數以特殊方式解釋的。
Rebol的方言能力的例子可以從單詞return
看出來。在「數據交換方言」中return
就是個沒有任何特殊含義的單詞。在「執行方言」中, return
是個全域變數,指稱傳遞迴一個函數結果值的一個原生函數[4] 。在「可視介面方言」(VID)中return
是一個關鍵字,導致佈局引擎去模擬一個Enter返回,移動「呈現筆」下至下一行的開始處[8]。
具有圖形能力的Rebol直譯器必須理解和解釋很多方言。下表按重要性依次列出最主要的方言。
語法
Rebol的語法是自由形式的,不要求特殊定位。但是,通常使用縮排來更好將文字結構傳達給人類讀者。
不同方言的語法屬性可以不同。對於所有Rebol方言的公共平台是「數據交換方言」;其他方言通常從它衍生。除了是所有方言的公共平台之外,「數據交換方言」直接用來表示數據和元數據、遷移(populate)數據結構,在互聯網上傳送數據,並把它們儲存在數據儲存中。
對比於程式語言比如C,「數據交換方言」不構成自聲明、陳述式、表達式或關鍵字。有效的「數據交換方言」文字流是樹數據結構,構成自塊(根塊是隱含的,子塊由方括號界定),圓塊(圓括號界定)、字串(雙引號或適用多行字串的花括號來界定;脫字元表示法用於不可列印字元)、URL、e-mail地址、檔案、路徑或其他複合值。不同於ALGOL的塊,Rebol的塊是複合(composite)值,類似於Lisp中參照起來的表達式。代碼以Rebol塊的形式寫成的事實,使語言具有同像性[4]。
塊還有圓塊可以包含由空白分隔的其他複合值(一個塊可以包含子塊、圓塊、字串等等)或純量值比如:word
(單詞)、set-word
(字尾着冒號的單詞)、get-word
(字首着冒號的單詞)、lit-word
(字首着撇號的單詞)[12],數字、錢款、字元等。注意在單詞中允許特殊字元,所以a+b
是一個單詞,不同於a + b
,它是空格分隔的三個單詞。
語意
最常用的求值器是do
函數。它被預設的用來解釋給直譯器控制台的文字輸入。
由do
函數解釋的「執行方言」,是一個面向表達式的「數據交換方言」的子語言。語言的主要語意單元是表達式。對比於衍生自ALGOL的指令式程式語言,「執行方言」既沒有關鍵字也沒有陳述式。
單詞被用作大小寫不敏感變數。像在所有動態型別語言中那樣,變數沒有關聯的類型,類型是關聯於值的。在do
函數遇到一個單詞的時候,返回對這個單詞的求值結果。set-word
單詞可以用於賦值。儘管沒有陳述式,賦值和有副作用的函數在一起,可以用於指令式編程[4]。
根塊的子塊自行用do
求值。塊作為直譯器實際參數這個性質被用來處理數據塊,通過把塊作為實際參數提交給控制函數如if
、either
、loop
等用於結構化編程,在把塊傳遞給特定直譯器函數時用於方言[7]。
值得注意的特殊問題是賦值給變數的複合值是不複製的。要製作一個複本,這個值必須傳遞給copy
函數[4]。
do
函數通常服從字首表示法求值,這裏函數處理跟隨在其後的實際參數。但是,也存在使用中綴算符的中綴求值。中綴求職優先於字首求值。例如:
abs -2 + 3
返回1
,因為中綴加法優先於計算絕對值。在求值中綴表達式的時候,求值的次序是從左至右,沒有算符優先於其他算符。例如
2 + 3 * 4
返回20
,對於乘法優先於加法的求值這將產生14。所有演算法都有字首版本。Do
在將實際參數傳遞給函數之前通常對實際參數進行求值。所以,下列表達式:
print read http://en.wikipedia.org/wiki/Rebol
首先讀取維基百科的Rebol頁面,接着把結果傳遞給print
函數。圓括號可以用來改變求值的次序。使用字首表示法,可以避免使用圓括號[4]。
這種簡單的優先級規則有如下優勢:
- 不需要在寫表示式的時候檢視優先級表格,
- 不需要在定義新算符的時候重寫優先級表格,
- 表達式可以輕易的從中綴轉寫成字首表示法或反之。
還有一個劣勢:
- 習慣了常規優先級規則的用戶容易出錯[7]。
parse
函數適合用於規定、驗證、變換和解釋方言。它通過在執行時間匹配「解析表達式」來完成工作[7]。
「解析表達式」是使用「解析方言」來書寫的,它類似於「執行方言」,是「數據交換方言」的面向表達式的子語言。不同於「執行方言」,「解析方言」使用關鍵字來代表算符和大多數重要的非終結符,中綴分析算符沒有字首等價者並使用優先級規則(序列優先於選擇)[7]。
動作也可以被包含而在解析處理期間進行,並且parse
函數可以被用來處理塊或字串。在「字串解析」層級,parse
必須處理「低層」解析,需要考慮到字元和界定符。「塊解析」是更高層級,處理在Rebol值的級別上的掃描[7]。
解析方言屬於由自頂向下解析語言或解析表達文法(PEG)為代表的文法家族。主要的類似性是所有家族成員都有序列和選擇算符的出現。解析方言的語法和在解析方言和PEG之間的類似性可以用分析算術表達式的PEG範例的如下轉寫來展示:
Digit: charset [#"0" - #"9"]
Value: [some Digit | "(" Expr ")"]
Product: [Value any [["*"| "/"] Value]]
Sum: [Product any [["+"| "-"] Product]]
Expr: Sum
parse/all "12+13" Expr
參照
延伸閱讀
外部連結
Wikiwand in your browser!
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.