高级程序设计语言原理课件_第1页
高级程序设计语言原理课件_第2页
高级程序设计语言原理课件_第3页
高级程序设计语言原理课件_第4页
高级程序设计语言原理课件_第5页
已阅读5页,还剩502页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

高級程式設計語言原理

第一章程式設計語言研究什麼是語言:語言是資訊交流工具。有如下幾種定義:1、Webster字典定義Anartificiallyconstructedprimarilyformalsystemofsignsandsymbols(assymboliclogic)includingrulesfortheformationofadmissibleexpressionsandfortheirtransformation基於一組記號與符號由人工構造的(基本上是)形式化的系統(如符號邏輯),包括合法運算式的形成規則和轉換規則。2、Longman字典定義Anysystemofsigns,movements,etc.,usedtoexpressmeaningsorfeelings任何表情達意的記號系統。3、英漢雙解電腦辭典定義(清華大學出版社)Asetofcharacters,conventionsandrules,thatisusedforconveyinginformation.Thethreeaspectsoflanguagearepragmatics,semanticsandsyntax一種用於傳遞資訊之字元、約定和規則的集合。語言的三個方面是語用、語義和語法。4、中國大百科全書,電子學與電腦卷語言的基礎是一組記號和一組規則,根據規則由記號構成之記號串的總體就是語言。5、徐家福:軟體語言及其實現語言是基於一組記號與一組規則、根據規則由記號構成之記號串的總體。任何語言均包括語法、語義和語用三個方面。語言的作用描述作用、交流作用和標誌作用(軟體語言可作為計算技術發展的里程碑標誌)語言是人類生活的必要工具,不同的語言被使用於不同的領域和方面在計算領域,也存在不同層次的語言,本書所論及的是實現層次的語言,即程式設計語言。程式設計語言=字元集+規則集(用於組合字元)任何用於描述演算法和數據結構的一套符號系統均可稱為程式設計語言本課程研究的對象:主要考慮那些在電腦上實現的程式設計語言術語所界定的範圍:術語“程式設計語言”並沒有一個公認的範圍定義通常這個術語是指高級語言電腦上語言的層次:純二進位機器碼或符號機器碼符號組合語言宏組合語言高級語言甚高級語言Byte或word,指令、數據不分用一些符號來代表指令,如sub代表減,Add代表加等,機器地址用十進位。有時組合語言等同於符號機器碼。變數名用符號,地址也可用符號而非數字。編制的程式稱為組合語言程式。用戶可以定義新指令及副程式根源程式編譯為目標程式,或解釋執行高級程式語言的高層規約語言,提供比高級程式語言更高級的語言設施。又稱為“可執行的規約語言”。有時也不區別於高級語言。程式設計語言的四個基本特徵:1、用戶不需要具有機器代碼的知識,只需學習特定的程式設計語言,並獨立於任何特定的機器代碼而使用。這並不意味著用戶可以完全忽略實際的電腦,如:需知道浮點數的表示或使用某些機器資源。2、程式設計語言必須有較大程度的機器獨立性(完全的機器獨立性)。這意味著必須有較大潛力,使得根源程式可運行在具有不同機器代碼的兩臺電腦上,不需要完全重寫。

3、當根源程式翻譯成機器代碼時,通常對每個執行單元有多個機器指令,如:A=A+B需多個機器指令來實現4、程式設計語言的記號比機器語言更接近於被求解的問題。如:A=A+B比其機器翻譯更易於理解。1.1為什麼研究程式設計語言兩個基本觀察:1、已有數百種語言被設計和實現。在1969年,Sammet就列出了當時120種相當廣泛使用的語言,在此以後,又有很多語言被開發。在早期,為一個專案的進行而開發一種語言是常有的事。2、大多數程式員通常不會同時使用多種語言,一般限制到1~2種。事實上,都是直接使用電腦上已有的語言如C、Ada、Fortran等。既然如此,為什麼要去研究各種不同的語言,有的語言甚至永遠不可能再被使用?學習、研究程式設計語言的理由不僅僅是停留於膚淺的對語言特性的瞭解和考慮深入瞭解根本性的語言設計概念及它們對語言實現的影響1、提高開發有效演算法的能力很多語言提供的特性如果被合適地使用,會給程式員帶來益處,但如被不合適地使用,將可能導致大量電腦時間浪費或使程式員出現耗時的邏輯錯誤。有可能一個長期使用某一語言的程式員也並不理解該語言的所有特性。如遞歸特性:是一個非常便利的程式設計語言特性如正確、合適使用,可得到優美和高效演算法的直接實現。如不正確使用,將可能導致執行時間的天文數字增長。如果程式員不知道遞歸蘊含的設計問題和實現困難,將難於使用這種結構;對遞歸原理和實現技術的瞭解可使程式員瞭解在特定語言中的遞歸的相對代價並通過其理解確定其使用是否合適。新的程式設計方法不斷在文獻中引入,如OO程式設計,邏輯程式設計和併發程式設計的使用均需要對實現這些概念的語言的詳細瞭解和掌握。2、改善對現行程式設計語言的使用通過對語言特性的實現細節的瞭解,可大大增加書寫高效的程式的能力。如:對數據結構,諸如數組、串、表、記錄等,如何被創建和操作的瞭解對遞歸的實現細節的瞭解以及對對象類如何被創建的瞭解將對書寫高效程式有很大幫助3、增加可使用的有用的程式設計結構的辭彙量語言對思維既有幫助,也有限制人們使用語言去表達思想,但語言也控制人如何思維,用字句中沒有直接表達的方式來思維是十分困難的。在解決一個問題時,要尋找合適的數據和程式結構,通常人們首先考慮他熟悉的語言中可直接表達的結構。研究各種語言提供的結構和這些結構被實現的方式,程式員可增加其編程辭彙。對實現技術的瞭解非常重要。如要使用一個結構,該結構在語言中沒有直接提供,程式員必須提供自己的實現(使用語言提供的基本結構)。如副程式控制結構、協同例程(coroutine)在很多程式中有用,但很少有語言直接提供協同例程特性。C或Fortran程式員可以設計程式來使用協同例程結構,然後將它們實現為C或Fortran程式(如果熟悉相關概念及實現)從而可以提供大型程式的正確控制結構。4、允許更好地選擇語言對程式設計語言知識的掌握可以允許程式員針對特定的專案,恰當地選取合適的語言,從而減少編碼工作量。如:C、Fortran、Ada可用於數值運算,Lisp、ML、Prolog可用於人工智慧應用。對每種語言的特性的長處和弱點的瞭解和掌握有利於程式員做出廣泛而正確的選擇。5、更易於學習新語言對自然語言語法結構的學習和瞭解可使對新語言的學習更容易對程式設計語言各種結構和實現技術的瞭解,也可使程式員能夠在需要時更容易地學習新語言6、更易於設計新語言很少有程式員把自己考慮為語言設計者,然而,任何程式都有一個用戶介面,這事實上也是某種形式的程式設計語言,用戶介面包括提供給用戶用於和程式通訊的命令和數據格式。大型程式,如文本編輯器、操作系統、圖形包的用戶介面的設計者,必須考慮很多存在於通用程式設計語言設計中的相同問題。如果程式員熟悉一般程式設計語言中的結構和實現方法,則程式設計將可以大為簡化。總之,程式設計語言的研究十分重要,包括語言特性和實現技術(特別是不同結構的運行時表示技術)等主要研究內容。程式設計語言的優點比機器或組合語言更易於學習。這涉及很多方面的問題,如一個極端強大的程式設計語言可能比一個只有十幾條指令的機器的組合語言更難學。但給定基本相同的複雜度,程式設計語言更易學(記號更接近問題域;更少關心物理硬體)程式設計語言書寫的程式更易於調試debug(程式更為短小;記號本身更自然,因此更多注意力可放在程式邏輯而非語法細節上)。程式更易於理解程式設計語言的記號自然起到了文檔的作用上述原因導致解決問題的時間和代價減少。程式設計語言的缺點編譯過程需要機器時間,它可能超過易於調試所節省的時間編譯器可能產生低效的代碼如果用戶不知道機器代碼或編譯器未提供合適的調試工具,則程式調試可能非常困難。程式設計語言的分類這是一個非常困難的問題,並沒有公認的定義。這裏給出一些術語,有些是相互交迭的,一個語言可能歸屬於兩個類別。面向過程的語言(procedure-oriented)用戶刻劃一個可執行操作集合,它將以某種順序完成,從而刻劃了一個過程。關鍵因素是這些明確可執行的操作,執行順序由用戶確定。非過程型語言(nonprocedural)這只是一個相對的術語,沒有人定義過,也不可能定義。意指用戶指定的順序步驟的減少程度,越接近於用戶只陳述問題而不指定求解步驟,語言就越是非過程的。更進一步,可以有一個有序的步驟序列,其中每一步是某種程度上非過程性的,或是一個可執行操作的集合,其順序用戶並沒有指定。兩種情形均導致更多的非過程性。在Fortran出現前,語句Y=A+B*C-D/E被認為是非過程性的。因為它不能寫成一個可執行單元和被任何系統翻譯。隨著編譯系統的發展,過去非過程的今天變成過程的,而今天非過程的,明天可能是過程的。當今非過程系統的例子如:RPG(報告生成器)或排序生成器,只需給定輸入和希望的輸出即可,過程將被自動完成。說明型語言(DeclarativeLanguage)——完全非過程的程式只定義做什麼,不需指定如何做,如函數式(歸約)、邏輯式(歸結、合一)語言及其它甚高級語言。面向問題的語言(problem-oriented)該術語有不同解釋和用法,最常見用法是強調一個語言易於對特定問題求解(相對組合語言),很多人將其用於針對非常特殊的應用領域。面向應用的語言(Application-oriented)這是極易誤解的、但廣為使用的術語。實際上,所有語言均是面向應用的,只是領域大小不同罷了。如:Fortran適合數值科學計算,Cobol適合商業數據處理PL/1則二者均適合,領域更廣,又稱通用(generalpurpose)語言,實際上很少有真正通用的語言一般考慮:數值科學應用,非數值應用(如形式代數),商業數值處理,串、表處理等更特殊的領域:網形、仿真、數控、設備檢查等專用語言(specialpurpose)用於滿足單一的目標(指定領域;對特殊應用易用;提高效率等)問題定義或規約語言(problem-defining,specification)文字地定義問題,或特別定義輸入、輸出,但不定義變換方法問題求解語言(problem-solving)可以完整地刻劃一個問題的求解,這也是一個相對的術語標注語言(reference)是一個確定的字元集,具有語言的格式。通常用唯一字元表示某概念或語言中的字元,不一定要適合電腦輸入。通常包含英文單詞(作為多單個字元),也可能提供固定符號集。不需要易讀。出版語言(publication)標注語言的變種,如A↑2變成A2。硬體語言(hardware)又稱hardwarerepresentation,是標注語言直接映射到合適的格式以利於電腦直接輸入。硬體語言本身和標注語言必須有很好映射,如**作為↑的硬體表示,begin用‘BEGIN’表示等1.2程式設計語言簡史程式設計的歷史很複雜,至今已很難於擬出一條全面清晰的發展軌跡。已有各種不同的總結方式。1978年,ACMSpecialInterestGrouponProgrammingLanguage(SIGPLAN)召開了一個會議,HOPL(HistoryofProgrammingLanguage),專門研討語言發展歷史。程式語言的早期發展語言發展可追溯到1945年,德國的KonradZuse設計了“Plankalkul”,未實現。1954年,Laning和Zierler開發了一個用於數學計算的高級語言,運行於M.I.T的Whirlwind上,這大概是第一個運行的編譯器。它可以書寫數學運算式(具有上、下標)、賦值、分叉、輸入/輸出、副程式,並處理微分方程。第一個廣泛使用的高級語言是Fortran。IBM的JohnBackus領頭在50年代中期完成,初衷是解決科學及工程計算,但後也用於更多領域,甚至寫編譯器。該語言證明了高級語言的可行性,奠定了後來語言研究的基礎。1958年,ACM和歐洲的GAMM聯合開發用於演算法處理的語言IAL(InternationalAlgebraicLanguage),最終修改變成了Algol60(早點的版本是Algol58),Algol58和Algol60導致了很多相關的程式設計語言研究和編譯技術開發的發展。在實踐方面Fortran有很大影響,但Algol帶動了語言的理論研究熱潮。50年代中期,RemingtonRandUnivac的GraceHopper及其同事設計了Flow-Matic,該語言面向商業數據處理,這是第一個面向英語的語言,並成為Cobol的主要源泉。1959年,在DoD贊助下,組織了一批電腦製造商和用戶開發了Cobol(CommonBusinessOrientedLanguage),該語言在商業數據處理領域的影響甚至大於Fortran在科學計算領域的影響。1958、1959可能是語言歷史上生產率最大的兩年。M.I.T的VictorYngve開發了Comit,這是串處理語言,用於翻譯自然語言。M.I.T的JohnMcCarthy和其學生開發了人工智慧語言Lisp。Lisp至今仍在使用,Comit後來變成了Snobol(Bell電話實驗室於60年代中期開發)科學計算和數據處理是電腦早期的主要應用,語言也是如此,向跨兩個領域的通用性發展。1959-1960,SystemDevelopmentCorporation和JulesSchwartz在Algol58基礎上開發了Jovial,這是第一次通用性嘗試。1963-1964,IBM和SHARE的一個聯繫計畫開發了第一個通用語言(跨兩個領域)PL/I。Algol68是隨後的一個大的語言計畫,這是一個全新的開發,而不僅僅是升版,其主要特性是正交性,它定義了少量的基本特徵和組合它們的系統規則,允許程式員定義新的數據類型及操作。下一個大的語言計畫是,1975年開始的DOD專案,目標是開發適合於嵌入式電腦系統的語言,此即Ada。1979年開始發佈,1980年定稿,成為後期開發、實現和標準化的基礎,Ada不僅僅是適合嵌入系統,可有更廣用途。隨著交互計算系統的出版,適合交互環境的語言開始出現。1963年,RandCorporation的J.CliffShaw開發了Joss.。1964年,DartmouthCollege的JohnKemeny和ThomasKurtz開發了廣為流傳的Basic。針對非數值數學計算(如形式代數操作)的需要。IBM的JeanSammet於1962-1964開發了Formac。MIT的JoelMoses於1970年代早期開發了Macsyma。專用領域語言開發。1956年,MIT的DouglasRoss為機床控制開發了APT。其他有:civilengineeriy:Cogo computer-assistedinstruction:Coursewriter equipmentcheckout:Atlas。1967~1977,在美國,在給定年度內使用的語言數大概是170種,同時,每年或每兩年有25—30的增減。1978年HOPL會議,討論的語言滿足如下標準:a.1967年時已出版並被使用。b.1977年仍在使用。c.在計算領域有很大影響。選出的語言有:Algol,Apl,APT,Basic,Cobol,Fortran,GPSS,Joss,Jovial,Lisp,PL/I,Simula,Snobol。80年代的兩個重要語言PASCAL(NiklausWirth,1968)和Ada未列入。PASCAL在70年代後期成為非常重要的語言,特別是在電腦教學方面。E.Sammet在“ProgrammingLanguage:HistoryandFuture”,CommunicationsoftheACM中列出了若干代表性語言:APT(AutomaticallyProgrammedTools)1956,第一個專用領域語言。Fortran(FORmulaTRANslation)1956,第一個廣泛使用的高級語言,為大量的科學和工程人員打開了使用電腦的大門。Flow-Matic1956,第一個商業數據處理語言,第一次強調“類英文”的語法。IPL-V(InformationProcessingLanguageV)1958,第一個表處理語言。Comit1957,第一個實用的串處理和模式匹配語言。Cobol(CommonBusiness-OrientedLanguage)1960,最廣泛使用的數據處理語言。具有類英文的語法和機器獨立性。Algol60(ALGOrithmicLanguage)1960,用於刻劃演算法。形式化語法定義,帶動了語言的理論和實現技術研究。Lisp(LIStProcessing)1960,引入了函數程式設計概念,基於表處理。Jovial(JulesOwnVersionofIAL)1960,第一次包含了科學計算,I/O資訊的邏輯操作、數據存貯和處理等能力。大多數Jovial編譯器用Jovial書寫。GPSS(General-PurposeSystemSimulator)1961,第一個仿真語言。Joss(JOHNNIACOpen-ShopSystem)1964,第一個互動式語言。Formac(FORmulaManipulationCompiler)1964,第一個廣泛使用的形式代數操作語言。APL/360(AProgrammingLanguage)1967,引入了許多高級操作子,允許很短的演算法,產生了看問題的新方式。Pascal1971,在一個小語言中引入了如賦類型的新概念,並以優美方式組合了各種著名結構。程式設計語言的角色早期,電腦非常昂貴,而程式員年薪不高,關鍵資源是電腦。因此,語言設計是為了更高效地執行程式,高級語言需和組合語言競爭。Fortran的主要設計者Backus在Fortran面世十年後曾說:坦率地講,我們當時未曾有過任何最模糊的關於FORTRAN及其編譯器將如何工作的想法。我們只是簡單地努力優化目標程式,運行時間,因為當時大多數人不相信你可以真正完成這樣的事。他們認為機器編碼的程式將是極端低效的,對很多應用都是不實用的。我們未曾想到的一個結果是:有這樣一個系統,它被設計為完全獨立於程式將最終運行於其上的機器。這後來證明是非常有價值的能力,但當時我們肯定未曾想到。我們的活動沒有任何組織。程式的每個部分由一到二人完成,除了極少數例外,他們完全負責他們所做的事情。事情無序地發展,當FORTRAN發佈時,我們面臨這樣一個事實:25000條指令將並不是全正確的,存在著大量將在大量使用後才會顯示出來的問題。60年代中期,程式設計發生了變化,機器價格下降,程式設計價格上升。程式移植的需求越來越多,軟體的維護佔用了大量的計算資源。此時的目標不再是編譯程序後使其高效地運行,高級語言的任務變成使其易於開發正確的程式以解決某給定應用領域中的問題。編譯技術成熟於60、70年代,語言技術以解決特定領域問題為中心,如:Fortran用於科學計算,COBOL用於商業應用,JOVIAL用於軍事應用,LISP用於人工智慧應用,以及Ada用於嵌入式軍事應用等。程式設計語言也會進化和消亡,如:Algol已不再使用,Cobol使用正在下降,Pascal的很多結構仍在Ada中存在,但其黃金時代已過去。仍在使用的舊語言也經歷了不斷的修訂以反應來自其他計算領域的影響,Fortran和Cobol已有多個標準化標本。Ada有1995年新標準。Lisp修訂後有Scheme和CommonLisp。C++和ML則反應了人們在設計和使用語言中獲得的經驗的混合。對語言的主要影響源自如下幾個方面:1、電腦能力電腦經歷了數代的巨大變化,操作系統成為語言基於的平臺(不再僅依靠硬體)。這些因素影響了高級語言的結構和使用語言特性的代價。2、應用應用領域有了很大變化,電腦應用已滲透到幾乎所有領域,新應用的需求影響了新語言的設計和舊語言的修訂。特別是近幾年,INTERNET的發展進一步拓廣的應用範圍。3、程式設計方法人們對書寫大型複雜系統的方法的深入研究和程式設計環境的變化也影響語言的發展。4、實現方法更好的實現方法影響到新語言中特性的選擇。5、理論研究使用形式化的數學方法,對語言設計和實現的概念基礎的研究加深了我們對語言特性的優勢和弱點的理解,從而影響語言中特性的選取,如“繼承”,因語義複雜,而被有的語言放棄。6、標準化標準化語言需要易於在不同電腦上實現,使程式易於移植,這對語言的設計影響是保守的,即輕易不引入新特性。一些重要的語言和技術影響:1951-55:硬體:電子管電腦,水銀延遲線記憶體方法:組合語言,基礎概念:副程式,數據結構語言:運算式編譯器的實驗性使用1956-60:硬體:磁帶記憶體,磁芯記憶體,電晶體電路方法:早期編譯技術,BNF文法,代碼優化,解釋器,動態存儲方法和表處理語言:FORTRAN,ALGOL58,ALGOL60,COBOL,LISP1961-65硬體:可相容的體系結構家族,磁片記憶體方法:多道程序設計操作系統,語法制導的編譯器語言:COBOL61,ALGOL60(修訂),SNOBOL,JOVIAL,APL符號體系1966-1970硬體:增加尺寸和速度並降低成本,小型電腦,微程式設計,積體電路方法:分時和互動式系統,優化編譯器,翻譯器書寫系統語言:APL,FORTRAN66,COBOL65,ALGOL68,SNOBOL4,BASIC,PL/1,SIMULA67,ALGOL-W1971-75硬體:微型電腦,小型電腦時代,小型大規模存儲系統,磁性記憶體的衰落和半導體記憶體的興起方法:程式驗證,結構化程式設計,軟體工程作為一門學科的早期發展語言:PASCAL,COBOL74,PL/1(標準),C,Scheme,Prolog1976-80硬體:商用品質的微機,大型大規模存儲系統,分佈式計算方法:數據抽象,形式化語義,併發、嵌入式、和即時程式設計技術語言:Smalltalk,Ada,FORTRAN77,ML1981-85硬體:個人電腦,第一代工作站,視頻遊戲,局域網,Arpanet方法:面向對象程式設計,互動式環境,語法制導編輯器語言:TurboPascal,Smalltalk80,Prolog的發展,Ada83,Postscript1986-90硬體:微機時代,工程工作站的上升,RISC體系結構,全域網,Internet方法:客戶/伺服器計算語言:FORTRAN90,C++,SML(標準ML)1991-95硬體:非常快的廉價工作站和微機,大規模並行體系結構,語音,視頻,傳真,多媒體方法:開放系統,環境框架,國家資訊基礎設施(資訊高速公路)語言:Ada95,過程語言(TCL,PERL)1996-2000硬體:二代Internet,機群,網路電腦(NC)方法:軟體構件技術,Agent,中間件,流覽器/伺服器計算,Internet計算語言:JAVA,XML,IDL(後兩種一個意義上不能算為程式設計語言)1.3程式設計語言的評價好語言的屬性1、清晰、簡單、一致(協調)程式設計語言既是思考演算法的概念框架,又是表達演算法的工具。語言對程式的幫助不僅在編碼階段,還會在此階段前較長一段時間,均有幫助。語言應該是提供清晰、簡單、一致的概念,用作演算法開發的基本原語。因此,希望有最少數量的不同概念及其盡可能簡單和規則的組合規則,稱為概念完整性。語言的語法對程式的書寫、測試、理解和修改有較大影響,因此,可讀性是一個中心問題。特別精簡或隱義的語言使程式易於書寫(對有經驗的程式員),但難於讀(當要修改時),如APL,甚至程式員本人過一段間後也難讀懂。有的語言幾乎相同的語句實際上代表了完全不同的事。因此,一條基本原則是,語義不同應在語法中完全反映出來。2、正交性意味著可以以所有可能的方式來組合語言特性以得到有意義的組合結果,如條件語句和任意運算式的組合。正交性使語言易學,程式易寫,因為不需記住太多的例外和特殊情況,缺點是:邏輯上不協調或極端低效的組合可能會被編譯器忽略。正交性在語言設計中是一個有爭議的屬性。3、應用自然性語言的語法應使得正確的使用可以允許程式結構反映出演算法的邏輯結構。理想地:直接將程式的設計翻譯為合適的反映演算法結構的程式語句。順序演算法、併發演算法、邏輯演算法等各有不同的自然結構。語言應提供合適的數據結構、操作、控制結構和麵向問題的自然語法。語言流行的主要原因之一便是對自然性的需要。特別適合某類應用的語言將大大簡化該領域程式的創建,如Prolog適合於推導,C++適合於OO設計。4、對抽象的支持即使對最自然的語言,在刻劃問題求解的抽象數據結構和操作與語言固有的特別的基本數據結構和操作間總是存在著差距。如C可能是一個合適的用於構造大學課程調度應用的語言,但抽象的數據結構如“學生”、“課程”、“授課老師”、“教室”等以及抽象操作“分配某學生到某課程”,“安排某課在某教室”等並不在C語言中提供,而它們對應用本身是非常自然的。程式員的任務之一便是為問題求解設計合適的抽象,然後用實際語言提供的更基本的特性來實現這些抽象。理想地:語言應允許數據結構、數據類型和操作作為自包含的抽象而定義,程式員可以將它們用在程式的其他部分(只需瞭解其抽象性質,而無需知道實現細節)。5、程式易於驗證程式的可靠性總是一個中心的問題,有很多技術驗證一個程式是否正確地完成所需功能。程式可以用形式化方法證明是正確的,也可以用桌面檢查方式非形式地證明正確性(讀程式文本)也可以用測試的方法,用測試數據輸入,檢查輸出結果是否滿足規約,對大型程式,可能需要這些方法的組合語言應該對程式驗證提供支持,其支持力度是選擇語言的主要標準之一。語義和語法結構的簡單性是簡化程式驗證的主要因素。6、編程環境語言的技術結構僅僅是影響其使用的一個方面,而合適的編程環境可以彌補語言技術上的弱點。編程環境包含很多因素:可靠的、有效的、有良好文檔的語言實現自然是首要因素。特殊的編輯器和測試包可以加速程式的創建和測試。維護和修改程式的多個版本的機制有利於大型程式的開發。7、程式的易移植性程式的易移植性是很多專案的重要目標。廣泛使用的和獨立於機器特性而定義的語言是易移植性的有用的基礎,如:Ada、Fortran、C、Pascal等有標準化定義的語言書寫的程式易移植性較好。8、使用代價代價是評價語言的主要元素,但具有不同的代價度量。a.程式執行代價在早期,代價主要是程式執行代價。因此,優化編譯器的實現、高效的寄存器的分配和高效的運行時支持機制的設計是非常重要的。程式執行代價對語言設計是重要的,但主要對將重複執行的大程式更為重要。目前,對很多應用、執行速度不再是主要考慮。對程式開發的更好診斷和更容易的用戶控制以及程式的維護也需要考慮,在此情況下,執行時間增加10%—20%,也是可容忍的。b.程式翻譯代價當Fortran或C等用於教學時,高效的翻譯(編譯)比高效執行更為重要。通常學生程式會多次編譯,而執行次數不多,需要快速、高效的編譯器。c.程式生成、測試和使用的代價對某類問題,求解應該在程式員最少投入的情形下被設計、編碼、測試、修改和使用。如:Smalltalk是價格有效的,求解一個問題的時間和努力均較少。對使用語言的總代價的考慮在很多情況下變得和傳統的代價同等重要。d.程式維護的代價研究表明,對較長時間運行的程式的代價不是初始設計、編碼、測試的代價而是整過生命週期代價(涉及開發和維護)。維護包括發現錯誤的修改、平臺的變化所需的修改、程式的擴展和加強。語言對維護的支持是非常重要的(長期運行的程式由多個人員維護,語言應有支持)語言的應用領域語言的使用依賴於所求解問題的應用領域,過去30年各種應用領域的語言已有很大變化。1、60年代的應用60年代的程式設計可分為四個基本類:商業處理、科學計算、系統程式設計、人工智慧應用。商業處理這類應用大多是大的數據處理系統,運行在大型機上,其基本特徵是:讀大量在多個磁帶設備上的歷史數據,讀少量的當前事務集,寫出一個新的歷史數據集。COBOL是這類應用的代表語言。商業應用還包括商業計畫、風險分析和“Whatif”方案(60年代,這樣一個應用通常需幾個月)。科學計算主要用於各種數學方程的求解,包括數值分析、微積分求解、統計,這是電腦的第一個應用領域,Fortran是最流行語言,其語法接近數學。系統操作系統和編譯器這類應用要求能夠訪問硬體的全部功能和資源,當時沒有有效的語言存在。組合語言是主要的選擇。Jovial(Algol的變體)曾用於美國DoD的一些專案,60年代末,PL/I可用於此目的。一個相關的應用領域是過程控制,由於當時電腦的龐大和昂貴,大多數過程控制應用是非常大的,如電站控制和自動裝配線控制。Forth語言專為此而設計,組合語言也常被使用。人工智慧其特徵是對大的數據空間的搜索演算法。LISP是主要語言。2、90年代的應用當前的情況遠較過去複雜,有更多的應用領域,可選語言也更多。商業處理COBOL仍然是主要語言,C和PL/1也時常被使用然而“Whatif”方案已完全改變,spreadsheet已完全改革該領域過去對典型的商業計畫程式需化一個程式員幾個月,現在可在幾小時內泡制出很多。第四代語言也開始進入此市場。4GL提供了基於窗口的程式員介面,易於訪問資料庫記錄,易於產生填空式的輸入表和優美的輸出報告,有時4GL編譯器產生COBOL程式作為輸出。科學計算Fortran仍有較大市場,C開始進入該領域。Fortran90加入了許多Ada和其他語言的特徵。系統軟體60年代末的C和後來的C++佔據了這個領域。C提供了非常高效的執行,允許程式員對操作系統和硬體的完全訪問,其他語言如:Modula、Pascal、現代BASIC也可用於此。Ada以支持系統軟體開發為目標,但從未達到其成為此領域主要語言的目標。組合語言的使用已成為過去。即時語言的需求也在增加,C、Ada、Pascal常用於此。AILISP仍在使用,只是改為Scheme和CommonLisp。Prolog是此領域的新軍。出版字處理系統有自己的輸入命令和輸出檔語法。TEX是常用的語言,它產生Postscript頁面描述語言(直接使用已不多見)。Process(處理)60年代,程式員通過命令操作電腦,現在常用程式來控制其他程式,如:每天半夜備份檔,自動回答電子郵件等。這樣的活動稱為處理,這需要專用的處理語言,例如有:UNIX中的Shell,DOS中的BAT等。新範型新的應用模型仍在研究中,ML用於類型理論研究,其用戶正在增長。Smalltalk是另一重要語言,它是OO語言的起源。JAVA的應用域也在逐步擴大。語言的標準化一個例子:inti;i=(1&&2)+3;這是一條C語言語句,該語句是否有效?i的值是什麼?要回答這個問題,三個方法是常用的。1.通過閱讀語言參考手冊以決定語句的含義2.在自己的電腦上寫一段程式查看其結果3.閱讀語言標準中的定義選擇2是常用的方法——簡單易行,因為語言概念和其特殊實現相關。直接查用戶參考手冊也是常用的。但選擇3較少用,因為很少有人看語言標準。選擇1、2意味著一個語言的概念是和其特殊實現相關的。但實現是否正確?如:移植一個程式到另一電腦上,仍能正確編譯嗎?通常語言設計涉及一些複雜的細節,各個廠商有不同的解釋,從而產生細微的執行行為上的差異。廠商也可能決定加入新的特性到語言中以增強其有用性,但新加入是否“合法”是一個問題,它有可能導致移植的困難。為解決這些問題,大多數語言有標準定義,所有實現應該符合標準,通常有兩種標準:1.業主標準(Proprietary)。開發並擁有語言的公司所給定的定義。這類標準通常不適合已廣泛使用的語言。實現上的變體會隨著很多增強和不相容而出現。2.合議標準(Consensus)。基於相關參與者的同意而由一個組織產生的標準。合議標準是保證語言實現一致性的主要方法。每個國家都有自己的標準化組織美國:AmericanNationalStandardInstitute,ANSI負責程式設計語言標準的是:ComputerBusinessEquipmentManufactureAssociation(CBEMA)的X3委員會。IEEE(InstituteofElectricalandElectronicEngineers)也開發相應標準。英國:BSI(BritishStandardsInstitute)國際:ISO(InternationalStandardsOrganization),在瑞士、日內瓦。標準開發遵循類似的過程在某一時間,一組人認為一個語言需要一個標準定義了,標準化組織將組織一批志願者來開發標準,當工作組提出標準後,讓更大範圍的人進行投票,不能達成共識的部分去掉,然後產生語言標準。從理論上說,這是一個好過程,然而,實際上標準制訂技術和政治因素參半,如:編譯器的製造商在標準化過程中均有財力投入,都希望標準按自己的思路走,從而避免改變自己的實現以及失去用戶群。標準的制定是一個合議的過程,不是每一個人按自己的方式辦,而是希望最終的語言能為所有人所接受。在意見不同時,有時不得不將有的特性排除在標準外。為了更好地使用標準,有三個值得強調的問題:1.時限:什麼時候開始標準化一個語言?Fortran於1966年開始標準化,當時已有很多不相容版本,從而導致了很多問題。另一個極端,Ada於1983年在有任何實現前即開始標準化,因此,並不清楚標準產生時是否有語言可以使用。第一批的Ada編譯器在87或88年才出現。人們應該儘早開始一個語言的標準化,只要有足夠的語言使用經驗即可,太晚則會導致很多不相容的實現。2.相符性——什麼意味著程式和編譯器符合標準程式符合標準——如果該程式只使用標準定義的特性編譯器符合標準——對一個給定的符合標準的程式,可以生成能夠產生正確輸出的可執行碼。這裏並未涉及對標準的擴充,如編譯器加了附加特性,則使用這些特性的程式將不合標準。標準通常強調符合標準的程度,大多數編譯器都加入了自己的特性。3.廢棄新的電腦結構需要新的語言特性。一旦我們標準化一個語言,幾年以後它可能會變得古怪。如:Fortran66標準就已過時,它沒有類型、嵌套控制結構、封裝、塊結構和其他現代特徵。一般每五年應復審標準,或者重新修訂或者丟棄。所有標準的一個問題是:遵循舊標準書寫的程式怎麼辦?重寫程式代價非常大,因此大多數標準需要向後相容。這樣也存在一些問題:具有廢棄結構的語言可能變得難以控制,更危險的是這些結構可能會對好的程式設計有害。目前,存在兩個相關概念:廢棄和反對(deprecate)廢棄——一個特性被廢棄是指:它是一個可能在下一個標準版本中丟棄的特性,這意味著,該特性仍然可用,但在5—10年內會被丟棄,這樣提前可為重寫作好準備。反對——反對特性將在下一個標準版本中變成廢棄的,新編寫的程式不應再使用此類特性。符合標準的編譯器允許有擴展,只要能正確地編譯符合標準的程式即可。大多數編譯器均有擴展,廠商加入特性以力爭擴大市場份額。這是導致語言發展的重要因素之一。學術界,人們並不關心這樣的標準,總是根據自己的研究擴展和修改語言。這也是語言發展的重要源泉。1.4環境對語言的影響語言的發展不能在真空中進行,支持語言的硬體對語言有很大影響。支持程式執行的外部環境稱為操作或目標環境。程式被設計、編碼、測試和調試的環境稱為宿主環境。通常可分為四類目標環境:批處理環境互動式環境嵌入式系統環境程式設計環境--互動式環境的特例批處理環境最早和最簡單的操作環境只含有外部數據檔數據檔→程式處理→數據檔稱為批處理:因為輸入數據聚集成批並成批處理。Fortran、C、和Pascal均是為批處理而設計的,當然也可用於互動式嵌入式環境。對語言設計的影響環境的影響可分為四個方面:I/O特性、錯誤和例外處理、時間設施和程式結構。批處理語言中,檔是大多數I/O特性的基礎。雖然檔可用作到終端的互動式I/O,但對交互I/O的特殊需要並不涉及。檔通常存貯定長記錄,而終端需要鍵盤上每輸入一個字元就讀入一次。嵌入系統需訪問特殊的I/O設備,批處理器則不作此考慮。批處理中,終止程式執行的錯誤是可接受的,但代價昂貴,因為錯誤糾正後,必須重複全部運行。同時,來自用戶的立即處理和糾正錯誤的幫助是不可能的。這樣語言的錯誤或例外處理機制強調在程式中進行錯誤/例外處理,使得程式可從大多數錯誤恢復,無終止地繼續執行碼。批處理的第三特徵是程式時間限制的缺乏。語言通常不提供監控或直接影響執行速度的設施。語言特性的實現也通常反映出時間限制的缺乏。程式結構通常包含一個主程序和一個副程式集合,如:C、Fortran、Pascal等。副程式完全由編譯器處理,編譯器在工作時間內很少和程式員交流。互動式環境當前的PC機和工作站大多如此使用,程式在執行過程中直接和用戶交互,從鍵盤或mouse接收數據並送到顯示器顯示。如字處理、遊戲、數據管理、CAI等。影響:互動式I/O完全不同於一般的檔操作.錯誤處理方式不同,一旦錯誤輸入,程式可能顯示錯誤消息並請求糾正,在程式中處理錯誤的設施並不重要,錯誤時終止程式通常是不可接受的。必須經常使用某種時間限制,至少必須有可以忍受的時間反應。有時,長時間不輸入會導致其他操作的調用。主程序的概念通常不存在。程式由一系列副程式構成,用戶在終端輸入“主程序”作為命令序列。和用戶的交互形式為:請求命令,按命令執行,請求另一命令。嵌入式系統環境一個用於控制一個大系統的部分的電腦系統稱為嵌入式系統(成為大系統的有機集成部分,其失誤將導致整個大系統的失敗)。可靠性和正確性是這類系統程式的主要屬性。影響:嵌入式系統的程式通常沒有操作系統的支持,也沒有通常的檔和I/O設備環境,程式必須和非標準的I/O設備直接交互,通常使用特殊的過程。因此,語言通常不考慮檔和麵向檔的I/O操作。特殊設備的訪問能力是必須提供的:通過訪問特殊的硬體寄存器、存儲位置中斷處理器或以彙編或其他低級語言書寫的副程式。錯誤處理是十分重要的。每個程式應準備好處理所有錯誤,採取適當的動作去恢復和繼續。程式終止是不可接受的,除非災難性的系統失誤。通常也無用戶提供交互幫助。錯誤處理還必須處理系統部件的失敗(除了一般的錯誤外)。嵌入系統總是涉及即時操作,即能對輸入作出及時反應並同時產生輸出,語言必須具有時間設施。嵌入式電腦系統通常是分佈系統,涉及多個電腦。這樣,運行的程式通常是一個併發執行的任務集,每個任務控制或監控一個局部。如果有主程序,也僅僅是為了初始化任務的執行,一旦初始化後,任務通常併發運行,且無限地運行,除非整個系統失敗或關閉。程式設計環境這是程式創建和測試的環境,和操作環境相比,它對程式設計影響稍小,然而,普遍的認識是:好的程式設計環境對程式生產有較大影響,程式設計環境通常包含一個支持工具的集合和調用它們的命令集(編輯器、調試器、驗證器、測試數據生成器、美化列印器等)。對語言的影響主要體現在兩個方面:分開編譯和部件裝配,程式測試和調試分開編譯——這對大型程式的實現非常重要分開編譯的困難在於:編譯一個副程式時,編譯器可能需要其他副程式或共用數據對象的資訊。所需指導的資訊包括:1、被調用副程式的參數的數量、類型、順序等的規約,允許編譯器檢查外部副程式的調用是否有效。其他副程式的書寫語言也是需要知道的,編譯器可以據此設置適當調用順序,以傳送數據和控制資訊。2、被引用變數的類型聲明是需要的,允許編譯器確定外部變數的存儲表示,使得引用可以用適合的訪問格式來編譯。3、外部定義而在內部聲明使用的數據類型的定義是需要的,允許編譯器分配存儲和計算局部數據格式。為了提供關於分開編譯的副程式、共用數據對象和類型定義的資訊,通常有三個方法:1、語言可能需要資訊在副程式中重新申明(如Fortran)。2、指定特殊的編譯順序,先編譯所需的外部資訊(如Ada、Pascal)3、需要在編譯過程中包含相關規約的庫的存在,使得編譯器可隨時查詢(Ada、C++)方法一又可稱為獨立編譯每個副程式可不需外部資訊而獨立編譯,副程式是完全自包含的。缺點是:沒有辦法檢查內外資訊的一致性。這種不一致錯誤只能在裝配階段才可能知道。方法二、三需要工具將副程式、類型定義和公共環境的規約放到庫中。通常副程式的體(body,含局部變數和語句)可以略去,只需規約。體部分可在以後分開編譯。如Ada中,每個副程式、任務或包分成兩個部分(可以分開編譯):規約和體。一個對尚未編譯的副程式的調用稱為Stub,包含Stub的副程式可以執行。但當到達Stub點時,該調用產生一個系統診斷資訊而不進行實際調用,從而可達到單獨測試目的。分開編譯影響語言設計的另一面是共用名(不同開發者可能對子程式類型定義、公共變數使用相同的名)的使用。通常解決共用名的方法有三:1、每個共用名必須是唯一的(由程式員來保證),如C中extern中的變數名。命名約定用於每個小組使用不同的副程式名(如固定的名字首碼),如C中的_綴。2、語言常使用作用域(Scope)(在嵌套情況下,只有最外層副程式中的名對外可知)規則來隱藏名字。3、通過顯式地加入來自外部的定義而使名字可用,OOPL的繼承即為這種機制,通過包含外部定義的類在一個副程式中,該類定義的其他對象也就自然可知。Ada中,名字可以重載,n個對象可有相同名字,需編譯器來指定實際的引用。測試和調試大多數語言會有輔助程式測試和調試的特性。1、執行追蹤。Prolog、LISP和很多其他交互語言提供了允許特殊語句和變數被標誌為執行時“追蹤”。當標記的語句被執行或標記的變數被賦新值時,程式的執行中斷,指定的追蹤副程式被調用。2、中斷點(Breakpoint)。在互動式編程環境中,語言常提供中斷點設施,當達到中斷點,執行中止,控制權交給程式員,他可檢查或修改變數值並且開始程式執行。3、斷言(Assertion)。斷言是一個條件運算式,插入在程式中。例:assert(x>0andA=1)or(x=0andA>B+10)斷言陳述了在指定點變數值間應有的關係。當斷言被“使能”,編譯器插入相應的代碼來測試被陳述的條件,條件不成立,則執行終止,調用例外處理。程式正確後,可將斷言設置掉重編譯,此時,它只作為注釋用。早期的語言設計需使程式能高效地運行於昂貴的硬體上,因此,早期語言總以翻譯成高效的機器碼為目標,既使程式難以書寫。現在,硬體價格下降、軟體價格上升,更強調程式容易書寫,即使慢點也可。例如,ML的類型特性、C++的類、Ada的Package均在執行速度上有代價,但對保證程式正確性有幫助。開發語言時,有三個影響語言設計的主要因素:電腦本身在電腦上支持語言的執行模型,即虛擬電腦語言所實現的計算模型2.1電腦的結構和操作一個電腦是能夠存儲和執行程式的數據結構和演算法的集成集合。電腦可構造為實際的物理設備,用導線、積體電路、電路板等。此即實際電腦或稱硬體電腦。電腦構造為軟體,用運行於其他電腦上的程式。此即軟體仿真電腦。程式設計語言的實現是通過一個翻譯器,將以語言書寫的程式翻譯為機器語言程式(可為某電腦直接執行,可以是硬體電腦,也可以為軟硬參雜的虛擬機)。一個電腦包含6個主要部件,它們緊密地對應於程式設計語言的主要方面。1、數據:電腦必須提供各種基本資料項目和操作的數據結構。2、基本操作:必須提供對運算元據有用的基本操作集。3、順序控制:必須提供控制基本操作執行順序的機制。4、數據訪問:必須提供控制向操作的執行供給數據的機制。5、存儲管理:必須提供控制程式和數據存儲分配的機制。6、操作環境:必須提供與包圍程式和被處理數據的外部環境通訊的機制。電腦硬體一個典型的傳統電腦組織如下:包括程式和被處理的數據操作主存和高速緩存中的數據在主存和外部環境間傳遞程式或數據完成處理工作取機器指令解碼調用指定的基本操作,以指定的運算元作為輸入數據有三個主要的存貯部件:主存,高速寄存和外部檔。主存:組織為線性位串,可分為定長的字(32或64)或8位位元組。寄存器:字長度的位串,可能有特殊的子域可直接訪問,可存數據或主存地址。外部檔:存在盤、帶或CD-ROM上,按記錄劃分,記錄是位或位元組的序列。一個電腦有被硬體基本操作直接操作的固有數據類型。一般有:整數、單精確度實數(浮點數)、定長字串、定長位串等。除了明顯的硬體數據元素外,程式(也有固有的內部表示,稱為機器語言表示)也是一種數據形式。機器語言程式可構造為存儲位置的序列,每個包含一或多條指令,每條包括操作碼和若干運算元(指示)。操作電腦必須包含有一個固有的基本操作集,通常和機器語言指令中操作碼一一對應。典型的操作集包括在固有數值類型上的基本算術操作。測試資料項目各種性質的基本操作。訪問和修改資料項目的基本操作。控制I/O設備的基本操作。順序控制的基本操作。傳統的機器是CISC,complexinstructionsetcomputers.新近發展的是RISC,reducedinstructionsetcomputers.更少的基本指令,更簡單的內部邏輯。順序控制程式地址寄存器(位置計數器)的內容決定了下一條將執行的指令,即包含了下條指令的地址。某些基本操作允許修改程式寄存器,從而傳遞控制到程式的其他部分。解釋器實際地使用程式地址寄存器並指導操作序列。解釋器是電腦操作的中心,其週期動作如圖所示:數據訪問除了操作碼外,每個機器指令必須指明所需的運算元(必須在主存或寄存器中)電腦必須結合指定運算元的手段和從給定運算元指示器檢索運算元的機制。同時,操作的結果也必須存儲在指定的位置。傳統的存儲控制機制是為存儲位置設定整數地址,提供操作從給定地址的位置檢索內容和存儲新值。寄存器也賦以整數地址。存儲管理機器設計的一個驅動原則是保持所有電腦資源盡可能多地被使用,中心衝突是:CPU中的操作是納秒級(一個操作10—50ns)訪問主存是是微秒級(0.1~0.2微秒,100—200ns)外部數據操作是毫秒級(15—30毫秒)這樣在內外速度間相差1000,000倍。為了平衡速度差異,各種存儲管理機制是必須的。1、在最簡單的設計(如低價PC)中,只有簡單的存儲管理設施。程式和數據執行時駐留記憶體,在一個時刻只有一個程式準備執行。雖然CPU必須等待數據,它也是價格有效的,因為不需加入附加硬體。2、為加速外部數據訪問和CPU間的平衡,操作系統常使用多道程序設計,當等待毫秒去讀數據時,電腦將執行另一個程式。為了保證多個程式同時駐留主存,通常有硬體設施負責頁面查找或動態程式重定位,頁面查找通過預測進行,預測在最近將來最可能使用的頁面,將其放入主存。如在主存,則程式執行,否則,出現頁間錯,操作系統將從外存中讀取所需頁,同時執行別的程式。3、為加速主存和CPU間的不平衡,常使用Cache記憶體(小的高速數據存儲)。Cache可允許電腦操作,好象主存具有和CPU相同速度,通常是1K到256K位元組,32K的Cache,可達到95%的選中率。操作環境電腦的操作環境通常包括週邊記憶體和I/O設備,這些設備表示了電腦的外部世界,和電腦的任何通訊必須通過它們。操作環境中通常有硬體的不同,如:高速存儲(擴展記憶體),中速存儲(磁片),低速存儲(磁帶)和I/O設備。各種電腦體系結構電腦硬體的組織有多種形式,上面的討論是基於VonNeumann體系結構。VonNeumann體系結構:命名來源於數學家JohnvonNeumann,他在40年代開發這個初始設計,作為ENIAC電腦設計的一部分,現今電腦仍屬此體系結構。多處理器:VonNeumann設計的最大問題是外部數據設備的慢速和CPU寄存器高速間的矛盾。解決方案之一是在指定系統中使用多個CPU,這樣的多處理系統已使用了30多年,通過幾個相對不昂貴的CPU的粘合,再加上單一的主存、磁片、磁帶等,得到一個高效系統。操作系統將不同程式運行於不同CPU上,從而整個性能得到改善。語言和系統設計正在演化,使得能夠書寫程式在多個電腦上執行並相互通訊。電腦狀態對電腦靜態組織的瞭解只是一個部分,全面瞭解則涉及電腦在程式執行時的動態操作,包括:執行開始時各存儲部件的內容,操作執行順序。執行進行時如何修改各種數據部件,程式執行的最後結果等。通常對電腦動態行為的觀察是通過電腦狀態(執行過程中某點主存、寄存器和外存的內容決定)的概念。程式的執行體現為一系列狀態的變化初始狀態通過一系列狀態變遷(從當前狀態通過存貯內容的修改進入新的狀態),得到最終狀態。如果我們可以預測狀態變遷序列,則可以聲稱瞭解了電腦的動態行為。固件電腦如前定義,電腦=演算法集+數據結構集 可執行程式表示為電腦的機器語言程式通常認為電腦操作在相當低級的機器語言之上,具有簡單的指令格式。然而,機器語言並不一定限制到低級。可以選擇任何程式設計語言,精確地刻劃數據結構集和定義程式執行規則的演算法,這樣該電腦的“機器語言”就是該高級語言。每個程式定義了電腦的初態,程式執行的規則定義了程式執行過程中狀態的變遷序列,程式執行結果由程式執行完成後電腦的終態決定。給定一個精確的電腦定義,總是可能將其用硬體實現,從而可使電腦的機器語言為C、Ada、或其他高級語言。如此考慮的一個重要的基本原則是:任何精確定義的演算法或數據結構可以用硬體實現。電腦簡單地是演算法和數據結構的集合,我們可以假定其硬體實現是可能的,不管其複雜度和相應的機器語言。實際的電腦通常有相當低級的機器語言。高級語言作為機器語言會使機器非常複雜,具應用靈活性較差。一個具有低級通用指令集和簡單的、無結構的主存和寄存器的電腦可以被編程為相當廣範圍的高效電腦。一個常用的選擇(相對於電腦的嚴格硬體實現)是固件電腦,由運行在特殊的微可偏程硬體電腦上運行的微程式來仿真。這種電腦的機器語言是絕對低級的微指令集,用微指令集可編碼得到微程式,微程式將仿真所希望的電腦的操作,並定義瞭解釋週期和各種基本操作。通常微程式本身駐留在特殊的只讀記憶體中,由宿主機硬體高速執行,這種電腦在執行速度上和硬體直接實現電腦無太大差別。電腦的微程式仿真有時可稱為emulation(仿真),該電腦稱為虛擬機,因為機器本身並不存在。翻譯器和軟體仿真電腦理論上,有可能直接構造硬體或固件電腦,運行任何特殊的程式設計語言,但構造這樣的電腦並不經濟。現實的考慮是實際電腦採用低級機器語言(基於速度、靈活性和價格考慮),編程仍以高級語言進行。語言實現者面臨的任務是如何使高級語言程式執行在實際電腦上,不管其機器語言。這個實現問題有兩個基本方案。1、翻譯(編譯)高級語言程式→翻譯器→等價的機器語言程式→硬體直接執行源語言→目標語言幾種特殊類型的翻譯器:A、彙編器目標語言:實際電腦的機器語言源語言:組合語言,機器語言的符號表示大多數指令是一對一的翻譯B、編譯器目標語言:彙編和機器語言源語言:高級語言C、裝配器或連接編輯器(loader/linkeditor)目標語言:實際的機器代碼源語言:幾乎相同於機器代碼,通常包含可重定位的機器語言程式和數據表(刻劃可重定位代碼為變成真正可執行所必須修改的地方)D、預處理器或宏處理器源語言:某種高級語言的擴展形式目標語言:同樣語言的標準形式。通常進行宏替換。高級源語言到可執行機器語言的翻譯通常涉及多個翻譯步驟,有時,編譯本本身也涉及多遍(多步),如:先產生某種中間形式。2、軟體仿真(軟體解釋)我們可以通過運行在另一臺宿主機上的程式仿真一臺電腦,其機器語言為高級語言。用宿主機的機器語言構造一個程式集(表達高級語言執行必需的演算法和數據結構),即用軟體構造運行於宿主機上的高級語言電腦,稱為高級語言電腦在宿主機上的軟體仿真(或軟體解釋)。仿真電腦接受高級語言程式作為輸入,主仿真器程式完成解釋演算法(解碼並執行語言),最後從程式產生輸出。軟體仿真和翻譯的不同:均以高級語言程式為輸入,但是,翻譯為目標碼後再運行於實際電腦上仿真電腦直接執行輸入程式翻譯器以物理輸入順序處理程式語句,每個語句只處理一次。仿真器以邏輯控制流處理程式,可能重複處理某些語句而完全忽略其他語句。純粹的翻譯和純粹的仿真形成兩個極端全翻譯是很少的,除了輸入語言和輸出語言非常相似,如組合語言。全仿真也非常少,除了操作系統控制語言或互動式語言情形。通常語言實現是二者的結合。如圖所示。翻譯和仿真各有不同優點有的程式結構最好翻譯成更簡單的形式,——如迴圈中語句多次執行,翻譯可省去解碼時間。有的方面最好保持原有形式,在執行時根據需要處理。翻譯的主要缺點是失去了關於程式的一些資訊。單個的高級語言語句比單條機器語言指令含有更多資訊。仿真的優缺點基本正好相反。不需要太多的空間來存儲代碼序列的多份拷貝。但解碼代價高。通常,如源語言結構在目標語言中有直接表示,則代碼擴展不太嚴重,可採用翻譯。其他情形,可採用仿真。是否程式執行時的基本表示為實際機器的機器語言,形成了語言劃分的基礎。1、編譯型語言。如:C、C++、Fortran、Ada等源語言翻成機器碼,仿真僅限於一些運行支持例程(用於仿真源語言中和機器語言沒有緊密類似的基本操作)。通過硬體解釋器,可實現更快的程式執行。當然,也可能有的部分仍採用軟體仿真,如數據控制結構和存儲管理。2、解釋型語言。如:LISP、ML、Prolog、Smalltalk等翻譯器不是產生機器代碼,而是產生某種中間形式,比源語言更易執行。然後使用軟體解釋器對中間代碼進行執行。通常執行慢,也需要對基本操作、存儲管理和其他語言特性的仿真,這類語言翻譯器很簡單,更多的複雜性在軟體仿真。2.2虛擬電腦和綁定時間電腦的構造方式1、通過硬體實現,直接使用物理設備2、固件實現,在合適的硬體電腦上使用微程式設計3、軟體仿真,在宿主機上用某種語言實現4、上述技術的組合,各自選擇合適的實現方式當一個程式設計語言被實現,程式執行時使用的運行時數據結構和演算法定義了一個電腦。類似電腦的固件實現,我們稱其為由語言實現定義的虛擬電腦。該虛擬機的機器語言是該語言的翻譯器產生的可執行程式(形式:對編譯是實際的機器碼形式;對解釋是某種任意結構);其數據結構是程式運行時使用的運行時數據結構;基本操作是那些運行時實際可執行的;順序控制、數據控制和存貯管理結構也是那些運行時使用的,不管其是用軟體、硬體或微程式表示。語法和語義語法:程式看起來象什麼。語法規則規定了如何書寫語句、聲明和其他語言結構。語義:對各種語法結構賦予的含義。在語言手冊和其他語言描述中,通常圍繞語言中的各種語法結構組織語言描述。典型地,給出語法(對一個語言結構,如語句、聲明),然後給出語義,BNF是主要的語法記號體系。本書的組織方式略有不同,圍繞和虛擬機相關聯的結構來組織,這種風格用用在虛擬機中的數據結構和操作來描述語言的語義。有時,這些數據結構和操作是直接和語言語法中的特殊結構相關聯的,而通常,這種聯繫並不是太直接。如:Pascal虛擬機中可能在程式執行中使用向量,而向量結構是在聲明中直接給出的;然而,虛擬機也可能有其他不能在程式中直接可見數據結構,如副程式“活躍記錄”的中心棧。這些“隱藏”的虛擬機結構和那些直接對應程式員寫在程式中的某些東西的“可見”結構一樣,對更好地瞭解語言同等重要。因此,這裏的討論是圍繞在虛擬機中看到的結構,而不僅僅是語法元素來進行的。一個特殊的虛擬機元素可能在程式中沒有語法表示;可被單個語法元素直接表示;可被幾個分開的語法元素表示(由翻譯器合起來產生一個虛擬機元素)。虛擬機和語言實現如果語言用它們的虛擬機來定義,使得每個語言和一個共同理解的虛擬機相關聯,則使用虛擬機來描述語言的語義是直接的。然而,語言定義通常是個體地對每個語法結構給出語義,語言定義僅隱含地刻劃了一個虛擬機。語言在不同電腦上的每次實現,實現者都會從語言定義中看到略微(或非常)不同的虛擬機。同一語言的兩個不同實現,可能使用不同的數據結構和操作集合(特別是在語法中隱藏的部分)。每個實現者有很大自由度確定自己的虛擬機結構,這些是他的語言實現的基礎。當語言在一特定電腦上實現時,實現者首先確定表示語言的語義解釋的虛擬機,然後通過基本電腦提供的軟、硬體元素來構造虛擬機。語言實現的組織和結構由實現者的許多細微決策確定,需考慮電腦各種軟、硬體設施和使用代價。例:虛擬機如有整數加和平方根操作,則整數加可直接用硬體提供的整數加來實現,平方根可用軟體仿真,使用一個副程式。整數變數x可直接用存儲位置實現,該位置存放x的值;也可帶有標記,由標記和指針(擴向存取x值的位置)構成)。實現者還需確定什麼通過翻譯處理?什麼在執行中解決?通常,如果在程式翻譯並建立運行時結構的過程中,採用了某些動作,則可以使用一個特定的表示虛擬機數據結構或操作的方式。如果實現者略去這些動作而簡化翻譯器,則不同的運行時表示可能是必須的。三個因素導致相同語言的不同實現1、實現者虛擬機概念的不同(隱含在語言定義中)2、宿主機提供的設施的不同3、實現者如何用宿主機提供的設施仿真虛擬機元素的選擇和如何去構造翻譯器支持這些虛擬機選擇的不同。電腦層次程式員以某種高級語言編程使用的虛擬機事實上形成了一個虛擬電腦層次。底層:實際的硬體電腦。通常程式員很少直接使用這個電腦,一般地,硬體機被一個或多個軟體層(或微程式)變換成一個虛擬機,它可能和硬體機有很大不同。二層:由稱為操作系統的例程集合定義的虛擬機(如微程式形成第二層,那麼這也可稱為第三層)。典型地,OS提供了一系列新的操作和數據結構的仿真(這不是由硬體直接提供的)。如:外部檔結構或檔管理原語。OS也從OS定義的虛擬機上刪去了某些硬體原語,使得它們不能由操作系統用戶直接訪問。如:關於I/O、錯誤監測、多道程序設計和多道處理的硬體原語。OS定義的虛擬機通常就是高級語言實現者使用的機器。三層:語言實現者提供了一個新的軟體層,運行於OS虛擬機上,仿真高級語言虛擬機的操作;也提供了翻譯器:將用戶程式翻譯成語言定義虛擬機的機器語言。四層:高級語言定義的虛擬機並不是層次的最後一層。實際上,程式員編制的程式形成了新的一層虛擬機。那麼,什麼是這個程式員定義的軟體仿真虛擬機的機器語言呢?(這個程式的輸入數據將由這個機器語言構成或寫成)。一旦程式員建立了一個程式,必須有一個“程式”在該程式定義的虛擬機上運行,這個“程式”通過選擇合適的輸入數據集合而寫成。這個概念之所以難於理解,是因為對很多程式而言,輸入數據非常簡單,僅僅可稱為最平凡的程式設計語言。如:排序程式的機器語言可認為是整數集,即以一定格式構成的整數表為程式。然而,明顯的是:每一個在我們上述層次上構造較低層次的程式員必須記住這個觀點,因為在每一層構造的程式和數據結構事實上表示了下一層程式員編程使用的虛擬機的仿真。上面討論中一個隱含的中心概念是:程式和數據是等價的。我們習慣於在編程中將對象區分為“程式”和“數據”,這通常是一種有用的直覺的區分,但如上所討論,這種區分是一種表面性的。在某語境中的程式可能在另外的語境中變成數據。如:我們寫Pascal程式,但對Pascal編譯器來說,該程式是被輸入處理的數據,其輸出是機器語言程式。如果觀察程式的執行,你會發現它又是執行電腦中解釋器的數據。我們總是將某程式的輸入等價為將被處理的數據或將被執行的程式。進一步考慮這個問題(等價性)。如:在C、Fortran語言中,表示可執行程式的存儲空間通常是和其數據空間分開的。但在LISP和Prolog中,則沒有不同,程式和數據是混合的,只有執行過程可將其區分開來。綁定和綁定時間不嚴格地說,一個程式元素到某特定特徵或性質的綁定,僅是從一個可能性質的集合中性質的簡單選擇。決定這個選擇的程式陳述或處理的時間稱為性質對元素的綁定時間。語言中有不同的綁定和不同的綁定時間。綁定時間的類型對綁定類型沒有簡單的分類,但可區分出一些主要的綁定時間。這裏,我們基於一個基本假設:程式的處理總是先翻譯,後執行。1、執行時(運行時)很多綁定是在程式執行過程中完成的。如:變數到值的綁定,變數到特定存儲位置的綁定(在很多語言中)。進一步可分為:a.進入副程式或塊時。大多數語言中,重要的綁定只限制發生在執行中進入副程式或塊時,如C、Fortran中形參到實參、以及形參到特定存儲位置的綁定。b.在執行中的任意點。某些綁定可以發生在程式執行中的任意點,如:變數通過賦值到值的綁定,以及在LISP、ML中,名字到存儲位置的綁定。2、翻譯時(編

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论