热门问题
时间线
聊天
视角
ALGOL 60
来自维基百科,自由的百科全书
Remove ads
ALGOL 60(源自ALGOrithmic Language 1960的縮寫),是在1960年創建的稱為「算法語言」的一種程式語言。它是以後來稱為ALGOL 58的「國際代數語言」為基礎,其官方後繼者是ALGOL 68,它們一起並稱為ALGOL語言家族。Algol 60引進了許多新的概念如:塊、詞法作用域、遞歸[2]、巴科斯-諾爾範式(BNF),它在程式語言設計和發展演化中有著巨大的影響力。
Remove ads
歷史
1960年,在巴黎舉行的討論會上,來自歐洲的諾爾、Bauer、Rutishauser、Samelson、范·韋恩加登、Vauquois、Woodger,與來自美國的佩利、巴科斯、麥卡錫、Katz、Wegstein和J. Green,共同發表了《算法語言ALGOL 60報告》[3]。戴克斯特拉實現了ALGOL 60語言的第一個編譯器。在1962年羅馬會議上,ALGOL 60報告得到了修訂,並於1963年出版[4]。
ALGOL 60是程序設計語言發展史上的一個里程碑,影響到其後的Simula、CPL、ALGOL W、ISWIM、BCPL、B、Pascal、C、Scheme等。它標誌著程序設計語言成為一門獨立的科學學科,並為後來軟體自動化及軟體可靠性的發展奠定了基礎。
Remove ads
ALGOL 60以及COBOL,是最初的企圖標準化的程式語言。ALGOL60曾經提出兩項ISO標準:
ALGOL 60在語言報告中沒有I/O設施;諸多實現以少有相互兼容的方式定義了自己的設施。迄今ALGOL 60已經有了至少70個擴充、擴展、派生和子語言[7]。
Remove ads
詞法
和分界符:
,
.
⏨
:
;
≔
␣
(
)
[
]
‘
’
在ISO 1672標準中,用:=
表示≔
(U+2254),用*
表示×
;用%
表示÷
,用**
或^
表示↑
;用>=
表示≥
,用<=
表示≤
,用<>
表示≠
;用@
表示科學記數法中指數運算的底數10
所用符號⏨
(U+23E8),用{
表示‘
,並且用}
表示’
,用空格
表示在字符串中的空白字符␣
(U+2423)。
ALGOL 60有24個關鍵字:
|
|
|
|
|
|
ALGOL 60不採用保留字的概念,但包括了標準函數名字作為限制標識符:
|
|
|
|
|
|
|
|
|
關鍵字寫法依賴於實現,常見的是一種叫做索繞(stropping)的方法,即將關鍵字大寫並包圍在兩個'
之間,例如將go to
寫為'GOTO'
。在ISO 1672標準中關鍵字還包括對特定符號的某種文字轉寫:
Remove ads
語義
在ALGOL 60中,「複合語句」被定義為:包圍在語句括號begin
和end
之間的成序列的語句,形成一個複合語句。塊被定義為:成序列的聲明,跟隨著成序列的語句,並被包圍在begin
和end
之間,形成一個塊;所有聲明以這種方式出現在一個塊中,並只在這個塊中有效。[25]
一個程序是特定的一個塊或複合語句,它不包含在另一個語句之中,並且不使用不包含在它之中的其他語句。在1976年的修改版語言報告中,程序只能包含在叫做「環境塊」的假定總是存在的一個虛構塊之中,除了可以使用在環境塊中聲明的過程標識符和函數指定符之外,不使用不包含在它之中的其他語句。
量(quantity)被區分出如下種類:簡單變量、數組、標籤、接轉(switch
列表由標籤組成[26])和過程。聲明負擔定義在程序中用到的量的特定屬性,並給它們關聯上標識符。聲明包括:類型聲明、數組聲明、接轉(switch
)聲明和過程聲明。量的作用域是語句和表達式的集合,在其中關聯於這個量的標識符的聲明是有效的。所有的塊,自動地介入名稱目錄(nomenclature)的一個新的層級:
- 在這個塊內出現的標識符,可以通過合適的聲明,而被指定為局部於所論及的這個塊。這個標識符在這個塊裡面的所表示的實體,不存在於它的外面。這個標識符在這個塊外面的所表示的任何實體,在這個塊裡面是不可見的。
- 除了表示標籤的標識符之外,一個標識符,如果出現在一個塊中,而且並非聲明於這個塊中,則它非局部於這個塊[27],就是說它在這個塊裡面和在緊鄰其外的層級中所表示的是同一個實體。
- 因為塊中的語句自身可以是一個塊,局部和非局部於一個塊的概念,必須遞歸地去理解,就是說非局部於一個塊
A
的一個標識符,可是亦可否地,非局部於A
是其中語句的塊B
。
這動態的蘊涵了:在通過begin
進入一個塊的時候,所有為這個塊聲明的標識符,假定了這個給定聲明的本性所蘊涵的意義(significance);如果這些標識符已經被外面的其他聲明所定義,這時它們被給予新的意義;在另一方面,並非為這個塊聲明的標識符,保持它們舊有的含義。在通過end
或go to
語句退出一個塊的時候,為這個塊聲明的標識符失去它們的局部意義。聲明可以標記上額外的聲明符own
,其效果為:在重新進入一個塊的時候,自有的這些量的值將不變更而仍是上次退出時的值,然而聲明的沒有標記上own
的變量的值是未定義的。
Remove ads
在描述算法處理的程序中,主要構成者是算術表達式、布爾表達式,和得到語句標籤的指定(designational)表達式。除了特定的分界符之外,表達式的構成者包括:邏輯值、數值、變量、函數指定式,和基本的算術、關係、邏輯運算符(operator)及順序運算符。用以形成語句的關鍵字,在ALGOL 60中被歸入順序運算符和分隔符之中。
變量是對一個單一值的指名(designation)。加下標(subscripted)變量指定(designate)多維數組的元素的值,這裡將數組元素稱為「組成元件」(component)[28]。函數指定式(designator)定義單一的數量值或邏輯值,它們是將給定的由過程聲明定義的規則集合,應用於固定的實際參數集合的結果。
現在通常將變量定義為抽象的存儲位置,它含有了被稱為一個值的某種已知或未知的信息量,並且配對了關聯的符號名字。在ALGOL 60中,某些語法單位,比如表達式及其構成者和數組標識符,被稱為擁有值。各種「類型」即integer
、real
和Boolean
,指稱(denote)值的基本的屬性。
在左圓括號和匹配的右圓括號之間的表達式(parenthesized expression)自行求值,而這個值被用於後續的計算之中;因此通過適當的圓括號放置,總是可以在表達式之內安排出想要的運算次序。
ALGOL 60將語句分為三類:無條件語句、條件語句和for
語句。賦值語句擔負將表達式的值,指派(assign)到一個或多個變量,或者在定義函數指定式的值的過程主體中指派到過程標識符;在作為指派目標的下標變量中出現的任何下標表達式,先於得出所指派之值的表達式,而按從左至右順序求值。空無的虛設(dummy)語句不執行任何運算。過程語句負擔實施調用一個過程主體的執行。
控制流程語句包括:go to
跳轉語句、條件語句、for
循環語句。go to
語句結合了無條件go to
和計算go to
二者,go to
語句不能從塊外跳轉到塊內的標籤,但可以跳轉進入複合語句。條件語句包括if
語句(即if <布尔表达式> then <无条件语句>
),和if
語句經由關鍵字else
與隨後的語句聯合在一起的形式(即<if语句> else <语句>
)。ALGOL 60在if
語句和for
語句中介入了子句概念,算術表達式、布爾表達式和指定表達式,可以是條件表達式(即if ~ then ~ else ~
)[29]。
由於變量和函數指定式二者的語法定義都包含表達式,表達式及其構成者的定義必須是遞歸的。由於成序列的語句,可以被組織成複合語句和塊,語句的定義必需是遞歸的。ALGOL 60採用了左遞歸的巴科斯範式(BNF)。
在ALGOL 60中,過程聲明擔負定義過程標識符所關聯的過程,其主要構成者是過程主體,它是一個語句或一段代碼。過程主體總是表現得如同一個塊,不管它是否有著塊的形式;故而標記了在過程主體內語句或者主體自身的標籤的作用域,永遠不能延伸超出這個過程主體[30]。
過程主體關聯著一個頭部,它規定了出現在過程主體內的代表形式參數的特定標識符。過程的參數傳遞有兩種求值策略:傳名調用和傳值調用。在過程聲明中,通過對形式參數名字前導value
來指定傳值調用,預設為傳名調用。在過程主體是用ALGOL語言寫的語句的情況下,過程語句執行它的效果,等價於在程序上進行下列操作的效果:
- 聲明為傳值調用的形式參數,都要被賦值即指派上對應的實際參數的值,這些指派被認為是在進入過程主體之前顯式進行的。其效果如同創建了包圍著這個過程主體的一個額外的塊,在其中所做的這些指派針對的是局部於這個虛構(fictitious)塊的變量,它們具有在相應規定中給出的類型。作為結論,傳值調用的變量,被認為非局部於過程主體,但是局部於這個虛構塊。
- 聲明為傳名調用的形式參數,在整個過程主體內,要被替代為對應的實際參數,並且只要語法上可能就對這些實際參數包圍上圓括號。在通過這個名字替代處理而插入的標識符,和已經存在於過程主體之內的其他標識符,二者之間的可能衝突,將憑藉對涉及到的(這個過程主體的)形式標識符或局部標識符的適合的系統性變更來避免[31]。
- 最終經過上述修改後的過程主體,被插入到過程語句的位置上並被執行。如果調用這個過程的位置,處在這個過程主體的任何非局部量[32]的作用域的外面,在通過這個過程主體替代處理而插入的標識符,和在這個過程語句或函數指定式所在位置上其聲明有效的標識符,二者之間的可能衝突,將通過(在發起調用的這個層級上)對後者標識符的適合的系統性變更來避免[33]。
對於定義函數指定式的值的過程聲明,在其過程主體中,必須出現具有過程標識符在其左側部份中的一個或多個賦值語句,其中至少有一個必須被執行;並且這個過程標識符所關聯的類型,必須通過以類型聲明符作為其過程聲明的最先符號的樣貌來聲明。最後那個這樣指派的值,被用來繼續此函數指定式在其中出現的表達式的求值。在這個過程主體中,這個過程標識符的不在賦值語句左側部份中的任何出現,指示了這個過程的激活(activation)。
兩個傳名調用形式參數,其對應的實際參數之間可能存在依賴關係,比如第一個是整數變量i
,而第二個是下標變量A[i]
,從而導致後者形式參數也依賴於前者形式參數,利用傳名調用和這種副作用可以實現Jensen設備[34];它典型的用於定義對應於的級數過程Sum(k, l, u, ak)
,它有兩個傳名調用的形式參數:索引變量k
和通項(general)表達式ak
。
對於交換兩個參數的值的swap(x, y)
過程,其過程主體定義為:t:=x; x:=y; y:=t
,這種依賴性副作用會導致可能出現異常行為,由於名字替代機制相當於宏展開(expansion),過程語句swap(i, A[i])
中下標變量A[i]
的下標i
未經求值,對應的過程主體就轉換成為:t:=i; i:=A[i]; A[i]:=t
。1964年IFIP工作組2.1制定了《SUBSET ALGOL 60報告》,在這個子集語言中對「完全的名字概念」(full name-concept)增加了一項限制:在名字替代(傳名調用)中,實際參數只能是一個標識符或字符串。
在過程的參數列表( … <参数分界符> … )
中,有可選的「) <字母串>: (
」樣式的參數分界符[35]。眾所周知的傳名調用實現採用了thunk[a][37]。Donald Knuth設計了「男人抑或男孩測試」,來區分編譯器是否正確的實現了「遞歸和非局部引用」,在這個測試中局部定義的函數將自身用作其所調用函數的傳名調用的實際參數。
Remove ads
例子
下面是語言報告中過程聲明的一個例子[b]:
procedure Absmax(a) Size:(n, m) Result:(y) Subscripts:(i, k);
value n, m; array a; integer n, m, i, k; real y;
comment 矩阵a,其大小为n乘m,其绝对值最大的元素
被传送到y,并且这个元素的下标是i和k。;
begin
integer p, q;
y := 0; i := k := 1;
for p := 1 step 1 until n do
for q := 1 step 1 until m do
if abs(a[p, q]) > y then
begin
y := abs(a[p, q]);
i := p; k := q
end
end Absmax
在1976年修改版語言報告的環境塊中,定義了輸入輸出過程:inchar
、outchar
、length
、outstring
、outterminator
、ininteger
、outinteger
、inreal
和outreal
,下面以其中的outinteger
作為演示例子:
procedure outinteger(channel, int);
value channel, int;
integer channel, int;
comment 将表示int的值的那些字符,
加上尾随的终结符传递到channel。;
begin
procedure digits(int);
value int; integer int;
begin
integer j;
comment 使用递归从右至左求值数字,
但从左至右打印它们。;
j := int ÷ 10;
int := int - 10 × j;
if j ≠ 0 then
digits(j);
outchar(channel, ‘0123456789’, int + 1)
end digits;
if int < 0 then
begin
outchar(channel, ‘-’, 1);
int := -int
end;
digits(int); outterminator(channel)
end outinteger
這裡調用到的outchar(channel, str, int)
,將在字符串str
中對應整數int
的值的那個字符,傳遞到通道channel
;outterminator(channel)
,用於輸出在數值之後的終結符(即空格、換行或分號)。此外,IFIP工作組2.1在1964年曾制定《ALGOL 60輸入輸出過程報告》,其中定義了insymbol
、outsymbol
、length
、inreal
、outreal
、inarray
和outarray
,這裡的多維數組採用了橫行為主(Row major)次序[38]。
參見
注釋與引用
外部連結
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads