導航:首頁 > 創造發明 > 如何創造一門語言

如何創造一門語言

發布時間:2021-06-15 22:25:49

Ⅰ 如何設計一門語言

為什麼要設計一門新語言?原因無非就兩個,要麼舊的語言實在是讓人受不了,要麼是針對領域設計的專用語言。後一種我就不講了,因為如果沒有具體的領域知識的話,這種東西永遠都做不好(譬如SQL永遠不可能出自一個資料庫很爛的人手裡),基本上這不是什麼語言設計的問題。所以這個系列只會針對前一種情況——也就是設計一門通用的語言。通用的語言其實也有自己的「領域」,只是太多了,所以被淡化了。縱觀歷史,你讓一個只做過少量的領域的人去設計一門語言,如果他沒有受過程序設計語言理論的系統教育,那隻能做出屎。譬如說go就是其中一個——雖然他爹很牛逼,但反正不包含「設計語言」這個事情。
因此,在21世紀你還要做一門語言,無非就是對所有的通用語言都不滿意,所以你想自己做一個。不滿意體現在什麼方面?譬如說C#的原因可能就是他爹不夠帥啦,譬如說C++的原因可能就是自己智商太低hold不住啦,譬如說Haskell的原因可能就是用的人太少招不到人啦,譬如說C的原因可能就是實在是無法完成人和抽象所以沒有linus的水平的人都會把C語言寫成屎但是你又招不到linus啦,總之有各種各樣的原因。不過排除使用者的智商因素來講,其實有幾個語言我還是很欣賞的——C++、C#、Haskell、Rust和Ruby。如果要我給全世界的語言排名,前五名反正是這五個,雖然他們之間可能很難決出勝負。不過就算如此,其實這些語言也有一些讓我不爽的地方,讓我一直很想做一個新的語言(來給自己用(?)),證據就是——「看我的博客」。
那麼。一個好的語言的好,體現在什麼方面呢?一直以來,人們都覺得,只有庫好用,語言才會好用。其實這完全是顛倒了因果關系,如果沒有好用的語法,怎麼能寫出好用的庫呢?要找例子也很簡單,只要比較一下Java和C#就夠了。C#的庫之所以好用,跟他語言的表達能力強是分不開的,譬如說linq(,to xml,to sql,to parser,etc),譬如說WCF(僅考慮易用性部分),譬如說WPF。Java能寫得出來這些庫嗎?硬要寫還是可以寫的,但是你會發現你無論如何都沒辦法把他們做到用起來很順手的樣子,其實這都是因為Java的語法垃圾造成的。這個時候可以抬頭看一看我上面列出來的五種語言,他們的特點都是——因為語法的原因,庫用起來特別爽。
當然,這並不要求所有的人都應該把語言學習到可以去寫庫。程序員的分布也是跟金字塔的結構一樣的,庫讓少數人去寫就好了,大多數人盡管用,也不用學那麼多,除非你們想成為寫庫的那些。不過最近有一個很不好的風氣,就是有些人覺得一個語言難到自己無法【輕松】成為寫庫的人,就開始說他這里不好那裡不好了,具體都是誰我就不點名了,大家都知道,呵呵呵。
好的語言,除了庫寫起來又容易又好用以外,還有兩個重要的特點:容易學,容易分析。關於容易學這一點,其實不是說,你隨便看一看就能學會,而是說,只要你掌握了門道,很多未知的特性你都可以猜中。這就有一個語法的一致性問題在裡面了。語法的一致性問題,是一個很容易讓人忽略的問題,因為所有因為語法的一致性不好而引發的錯誤,原因都特別的隱晦,很難一眼看出來。這里我為了讓大家可以建立起這個概念,我來舉幾個例子。
第一個例子是我們喜聞樂見的C語言的指針變數定義啦:
int a, *b, **c;

相信很多人都被這種東西坑過,所以很多教科書都告訴我們,當定義一個變數的時候,類型最後的那些星號都要寫在變數前面,避免讓人誤解。所以很多人都會想,為什麼要設計成這樣呢,這明顯就是挖個坑讓人往下跳嘛。但是在實際上,這是一個語法的一致性好的例子,至於為什麼他是個坑,問題在別的地方。
我們都知道,當一個變數b是一個指向int的指針的時候,*b的結果就是一個int。定義一個變數int a;也等於在說「定義a是一個int」。那我們來看上面那個變數聲明:int *b;。這究竟是在說什麼呢?其實真正的意思是「定義*b是一個int」。這種「定義和使用相一致」的方法其實正是我們要推崇的。C語言的函數定義參數用逗號分隔,調用的時候也用逗號分隔,這是好的。Pascal語言的函數定義參數用分號分隔,調用的時候用逗號分隔,這個一致性就少了一點。
看到這里你可能會說,你怎麼知道C語言他爹就是這么想的呢?我自己覺得如果他不是這么想的估計也不會差到哪裡去,因為還有下面一個例子:

int F(int a, int b);
int (*f)(int a, int b);

這也是一個「定義和使用相一致」的例子。就第一行代碼來說,我們要如何看待「int F(int a, int b);」這個寫法呢?其實跟上面一樣,他說的是「定義F(a, b)的結果為int」。至於a和b是什麼,他也告訴你:定義a為int,b也為int。所以等價的,下面這一行也是「定義(*f)(a, b)的結果為int」。函數類型其實也是可以不寫參數名的,不過我們還是鼓勵把參數名寫進去,這樣Visual Studio的intellisense會讓你在敲「(」的時候把參數名給你列出來,你看到了提示,有時候就不需要回去翻源代碼了。
關於C語言的「定義和使用相一致」還有最後一個例子,這個例子也是很美妙的:

int a;
typedef int a;

int (*f)(int a, int b);
typedef int (*f)(int a, int b);

typedef是這樣的一個關鍵字:他把一個符號從變數給修改成了類型。所以每當你需要給一個類型名一個名字的時候,就先想一想,怎麼定義一個這個類型的變數,寫出來之後往前面加個typedef,事情就完成了。
不過說實話,就一致性來講,C語言也就到此為止了。至於說為什麼,因為上面這幾條看起來很美好的「定義和使用相一致」的規則是不能組合的,譬如說看下面這一行代碼:

typedef int(__stdcall*f[10])(int(*a)(int, int));
這究竟是個什麼東西呢,誰看得清楚呀!而且這也沒辦法用上面的方法來解釋了。究其原因,就是C語言採用的這種「定義和使用相一致」的手法剛好是一種解方程的手法。譬如說int *b;定義了「*b是int」,那b是什麼呢,我們看到了之後,都得想一想。人類的直覺是有話直說開門見山,所以如果我們知道int*是int的指針,那麼int* b也就很清楚了——「b是int的指針」。

因為C語言的這種做法違反了人類的直覺,所以這條本來很好的原則,採用了錯誤的方法來實現,結果就導致了「坑」的出現。因為大家都習慣「int* a;」,然後C語言告訴大家其實正確的做法是「int *a;」,那麼當你接連的出現兩三個變數的時候,問題就來了,你就掉坑裡去了。
這個時候我們再回頭看一看上面那一段長長的函數指針數組變數的聲明,會發現其實在這種時候,C語言還是希望你把它看成「int* b;」的這種形式的:f是一個數組,數組返回了一個函數指針,函數返回int,函數的參數是int(*a)(int, int)所以他還是一個函數指針。
我們為什麼會覺得C語言在這一個知識點上特別的難學,就是因為他同時混用了兩種原則來設計語法。那你說好的設計是什麼呢?讓我們來看看一些其它的語言的作法:

C++:
function<int __stdcall(function<int(int, int)>)> f[10];

C#:
Func<Func<int, int, int>, int>[] f;

Haskell:
f :: [(int->int->int)->int]

Pascal:
var f : array[0..9] of function(a : function(x : integer; y : integer):integer):integer;


這些語言的做法,雖然並沒有遵守「定義和使用相一致」的原則,但是他們比C語言好的地方在於,他們只採用一種原則——這就比好的和壞的混在一起要強多了(這一點go也是,做得比C語言更糟糕)。
當然,上面這個說法對Haskell來說其實並不公平。Haskell是一種帶有完全類型推導的語言,他不認為類型聲明是聲明的一部分,他把類型聲明當成是「提示」的一部分。所以實際上當你真的需要一個這種復雜結構的函數的時候,實際上你並不會真的去把它的類型寫出來,而是通過寫一個正確的函數體,然後讓Haskell編譯器幫你推導出正確的類型。我來舉個例子:

superApply fs x = (foldr id (.) fs) x


關於foldr有一個很好的理解方法,譬如說foldr 0 (+) [1,2,3,4]說的就是1 + (2 + (3 + (4 + 0)))。而(.)其實是一個把兩個函數合並成一個的函數:f (.) g = \x->f(g( x ))。所以上述代碼的意思就是,如果我有下面的三個函數:
add1 x = x + 1
mul2 x = x * 2
sqr x = x * x


那麼當我寫下下面的代碼的時候:

superApply [sqr, mul2, add1] 1
的時候,他做的其實是sqr(mul2(add1(1)) = ((1+1)*2) * ((1+1)*2) = 16。當然,Haskell還可以寫得更直白:
superApply [(\x->x*x), (*2), (+1)] 1


Haskell代碼的簡潔程度真是喪心病狂啊,因為如果我們要用C++來寫出對應的東西的話(C語言的參數無法是一個帶長度的數組類型所以其實是寫不出等價的東西的),會變成下面這個樣子:

template<typename T>
T SuperApply(const vector<function<T(T)>>& fs, const T& x)
{
T result = x;
for(int i=fs.size()-1; i>=0; i--)
{
result = fs[i](result);
}
return result;
}


C++不僅要把每一個步驟寫得很清楚,而且還要把類型描述出來,整個代碼就變得特別的混亂。除此之外,C++還沒辦法跟Haskell一樣吧三個函數直接搞成一個vector然後送進這個SuperApply裡面直接調用。當然有人會說,這還不是因為Haskell裡面有foldr嘛。那讓我們來看看同樣有foldr(reverse + aggregate = foldr)的C#會怎麼寫:

T SuperApply<T>(Func<T, T>[] fs, T x)
{
return (fs
.Reverse()
.Aggregate(x=>x, (a, b)=>y=>b(a(y)))
)(x);
}


C#基本上已經達到跟Haskell一樣的描述過程了,而且也可以寫出下面的代碼了,就是無論聲明和使用的語法的噪音稍微有點大……

SuperApply(new Func<T, T>[]{
x=>x*x,
x=>x*2,
x=>x+1
}, 1);


為什麼要在討論語法的一致性的時候說這些問題呢,在這里我想向大家展示Haskell的另一種「定義和使用相一致」的做法。Haskell整個語言都要用pattern matching去理解,所以上面的這段代碼

superApply fs x = (foldr id (.) fs) x
說的是,凡是你出現類似superApply a b的這種「pattern」,你都可以把它當成(foldr id (.) a) b來看。譬如說
superApply [(\x->x*x), (*2), (+1)] 1
其實就是
(foldr id (.) [(\x->x*x), (*2), (+1)]) 1
只要superApply指的是這個函數,那無論在什麼上下文裡面,你都可以放心的做這種替換而程序的意思絕對不會有變化——這就是haskell的帶有一致性的原則。那讓我們來看看Haskell是如何執行他這個一致性的。在這里我們需要知道一個東西,就是如果我們有一個操作符+,那我們要把+當成函數來看,我們就要寫(+)。如果我們有一個函數f,如果我們要把它當成操作符來看,那就要寫成`f`(這是按鍵!左邊的那個符號)。因此Haskell其實允許我們做下面的聲明:
(Point x y) + (Point z w) = Point (x+z) (y+w)
(+) (Point x y) (Point z w) = Point (x+z) (y+w)

(Point x y) `Add` (Point z w) = Point (x+z) (y+w)
Add (Point x y) (Point z w) = Point (x+z) (y+w)


斐波那契數列的簡單形式甚至還可以這么寫:

f 1 = 1
f 2 = 1
f (n+2) = f(n+1) + f(n)


甚至連遞歸都可以寫成:

GetListLength [] = 0
GetListLength (x:xs) = 1 + GetListLength xs


Haskell到處都貫徹了「函數和操作符的替換關系」和「pattern matching」兩個原則來做「定義和實現相一致」的基礎,從而實現了一個比C語言那個做了一半的混亂的原則要好得多的原則。
有些人可能會說,Haskell寫遞歸這么容易,那會不會因為鼓勵人們寫遞歸,而整個程序充滿了遞歸,很容易stack overflow或者降低運行效率呢?在這里你可以往上翻,在這篇文章的前面有一句話「好的語言,除了庫寫起來又容易又好用以外,還有兩個重要的特點:容易學,容易分析。」,這在Haskell裡面體現得淋漓盡致。
我們知道循環就是尾遞歸,所以如果我們把代碼寫成尾遞歸,那Haskell的編譯器就會識別出來,從而在生成x86代碼的時候把它處理成循環。一個尾遞歸遞歸函數的退出點,要麼是一個不包含自身函數調用的表達式,要麼就是用自身函數來和其它參數來調用。聽起來比較拗口,不過說白了其實就是:

GetListLength_ [] c = c
GetListLength_ (x:xs) c = GetListLength_ xs (c+1)
GetListLength xs = GetListLength_ xs 0


當你寫出這樣的代碼的時候,Haskell把你的代碼編譯了之後,就會真的輸出一個循環,從而上面的擔心都一掃而空。
實際上,有很多性能測試都表明,在大多數平台上,Haskell的速度也不會被C/C++慢超過一倍的同時,要遠比go的性能高出許多。在Windows上,函數式語言最快的是F#。Linux上則是Scala。Haskell一直都是第二名,但是只比第一名慢一點點。
為了不讓文章太長,好分成若干次發布,每次間隔都較短,所以今天的坑我只想多講一個——C++的指針的坑。剩下的坑留到下一篇文章裡面。下面要講的這個坑,如果不是在粉絲群裡面被問了,我還不知道有人會這么做:

class Base
{
...
};

class Derived : public Base
{
...
};

Base* bs = new Derived[10];
delete[] bs;


我想說,這完全是C++兼容C語言,然後讓C語言給坑了。其實這個問題在C語言裡面是不會出現的,因為C語言的指針其實說白了只有一種:char*。很多C語言的函數都接受char*,void*還是後來才有的。C語言操作指針用的malloc和free,其實也是把他當char*在看。所以當你malloc了一個東西,然後cast成你需要的類型,最後free掉,這一步cast存在不存在對於free能否正確執行來說是沒有區別的。
但是事情到了C++就不一樣了。C++有繼承,有了繼承就有指針的隱式類型轉換。於是看上面的代碼,我們new[]了一個指針是Derived*類型的,然後隱式轉換到了Base*。最後我們拿他delete[],因為delete[]需要調用析構函數,但是Base*類型的指針式不能正確計算出Derived數組的10個析構函數需要的this指針的位置的,所以在這個時候,代碼就完蛋了(如果沒完蛋,那隻是巧合)。
為了兼容C語言,「new[]的指針需要delete[]」和「子類指針可以轉父類指針」的兩條規則成功的沖突到了一起。實際上,如果需要解決這種問題,那類型應該怎麼改呢?其實我們可以跟C#一樣引入Derived[]的這種指針類型。這還是new[]出來的東西,C++裡面也可以要求delete[],但是區別是他再也不能轉成Base[]了。只可惜,T[]這種類型被C語言佔用了,在函數參數類型裡面當T*用。C語言浪費語法罪該萬死呀……

Ⅱ 編程語言是如何創建的

因為有解釋器啊,編譯型的語言一般都被轉化成底層的機械碼了。要想自己開發語言完全是沒問題的。至於看什麼《編譯原理基礎》感覺價值不大,能真正看懂的人太少了。還不如直接找個開源的程序語言研究一下。至少改個語法應該沒問題。

Ⅲ 可以自己創造一種語言嗎

語言都是人創造出來的 所以答案是肯定的但是 前提是在以擁有的語言中才能創造 當然 也可以當版作是自己的暗號不權過呢 如果只有自己才能看懂的那就不叫語言了 語言的意思簡單來說就是人與人通過說看寫來傳達自己的意思 沒有人看的懂也就不能成為語言 只能說是暗號中國的詞彙量不是一般的大 若是毅力頑強的你執意要去做 希望你能成功

Ⅳ 如何自創一門編程語言

我也有這種想法,不過我查過很多資料,要想自己創造一門編程語言(我說的內是中文編程語言),需要從頭開始容,比如,從機器代碼開始,創造出中文的匯編語言,然後從中文匯編語言創造出高級中文編程語言。編程語言是為了讓計算機知道我們到底想讓它做些什麼。所以從頭開始是最簡單的事情,但也是最難的事情,單單是其中低級轉到高級語言中的轉換解釋就需要很多知識。我說的不是那種把英文單詞改成中文單詞那種。而是改變結構,語法分析等等。現在我還在研究,但是很多東西真的不懂。因為不是母語,所以看不懂英文教材。也記不住基本的英文指令代碼。更加不理解到底是什麼意思。哎。加油。

Ⅳ 如何自己創造一門語言

創造不是很難,難的是被別人採用。語言是交際的工具,一個人創造的要是沒人採用,有什麼用?
創造一套密電碼還差不多。

Ⅵ 如何自創一門語言

這個是不可能的,創造語言需要經歷長時間的發展與很多人的加入與發展。

Ⅶ 一門編程語言是怎麼創造出來的呢

所謂計算機語言只是一個抽象的規范,而編譯器是這個規范的實現,它是在這內個規范的嚴格定義下容被實現的.

說的通俗一點,語言就像一份製造汽車的圖紙,他規定了
汽車應該有什麼,擁有什麼功能,等等各個方面,而編譯器就是一量根據這張圖紙製造出來的汽車,它實現了圖紙的定義,這樣你才能真正的使用這量汽車.

如果你有OOP的方面的知識,那可以把語言和編譯器比喻成類和對象的關系.

他們誰也離不開誰,只有兩部分共同合作,你才能使用這個語言.

Ⅷ 如何自創一門編程語言

從你的描述來看,自創一門編程語言是非常困難的。現在的編程語言都是幾十年前專研屬究人員做出來的,他們為編程語言做出了很大的貢獻。
如果自創一門編程語言的話,幾乎是不可能的,就算一個國家,集一國之力也很難做出來。

Ⅸ 人類語言是怎樣產生的

需要特別提出的是語言的產生以及它對腦髓發展的影響。「語言是從勞動中並和勞動一起產內生出來的」。原容始人類在狩獵、採集植物、製造石器等活動中,需要共同協作,「已經到了彼此間有些什麼非說不可的地步了」,於是便產生了一定音節和一定內容相結合的語言。

最初的語言起初的語言自然是十分簡單的,後來隨著勞動的不斷發展才逐步完善和豐富起來。在語言發展的過程中,古猿的發音器官——喉管也逐漸改造成為人的喉管。

語言的作用語言是表達思想的工具,由於語言的產生,使人們彼此間可以交流經驗,因此獲得的間接經驗就更多。在文字產生以前,語言對人類知識的傳播和積累,從而對人類認識世界和改造世界,有著重大作用。「有聲語言在人類歷史上是幫助人們脫出動物界、結成社會、發展自己的思維、組織社會生產、同自然力量作勝利的斗爭並取得我們今天的進步的力量之一。」

Ⅹ 怎麼研發一款編程語言

編程語言,作為人與計算機溝通的橋梁,有著重要和深遠的意義。有過計算機編程經驗的人,多少學習或掌握過一到多種編程語言。計算機專業領域的編程語言成百上千種,主流的編程語言也有數十種之多。每種編程語言面向的領域和特性都不盡相同,不過歸根結底是為了解決人與計算機之間溝通的效率問題,提高計算機的生產力。想必有不少人對那些主流編程語言的創造者十分傾佩,也相信有不少人會好奇一門編程語言是如何誕生的。那麼如何創造一門編程語言呢?
總的來看,創造一門編程語言需要有以下幾個過程:
(1)設計語言的特性。
(2)定義語言的單詞、語法和語義。
(3)實現編譯器或者解釋器將程序翻譯為計算機底層表示。
(4)生成計算機程序的二進制存儲格式。
(5)完善語言的運行時環境和標准庫。

一、語言特性設計
所謂語言特性,就是編程語言為開發者提供了什麼樣的原子性功能特徵。比如是否支持數學表達式計算、字元串處理,是否支持變數、函數和遞歸,是否支持分支、循環復合語句等。語言的變數類型是強類型、弱類型,還是動態類型,程序是過程式、函數式,還是面向對象的。是否支持模板、泛型和反射機制,是否支持多線程和並發特性,是否支持錯誤和異常處理機制等等。
語言特性設計是一門編程語言最關鍵的環節,直接決定了語言的基本特徵和雛形。當然,這也是最難的一個環節,因為語言設計是面向具體問題領域的,是語言設計者從大量的編程實踐中的獲得的總結和升華。比如C語言設計者希望面向計算機底層,擁有對操作系統和硬體的直接操縱能力。而Python的設計者則希望盡可能地減少操作計算機資源的繁瑣過程,以獲得語言的簡潔性、高度的靈活性和擴展性。SQL的設計者面向具體的數據查詢和分析領域,希望幫助開發者獲得快速檢索和操縱數據的能力。而Go語言的設計者則希望在保留C語言優秀功能的基礎上,擴展編程語言對高並發環境的支持,並擁有垃圾回收和快速編譯的能力。
凡此種種,編程語言特性的設計都是面向具體的問題領域的,是語言設計者構建於開發者和計算機之間的中間層,是對開發過程中重復功能邏輯的原子性「封裝」,最終的目的是為了提升具體問題領域內的軟體開發效率。

二、單詞、語法和語義
和人類使用的自然語言類似,編程語言也有自身的單詞、語法和語義,專業上稱為詞法記號、語言文法和語義。
常見的詞法記號可以分為數字、字元、字元串、標識符、關鍵字,以及用於連接表達式的運算符、分割語句或者程序段落的界符等符號。這些是編程語言程序的基本單位,通過它們的有序組合,構建出了一門編程語言形形色色的代碼片段。
編程語言的文法是用來描述語言的語法規則的,具體來說是規定詞法記號之間的排列組合的順序與規則。它描述了編程語言程序的基本模式,不符合該模式的詞法記號的排列被擋在了合法語言程序的大門之外。同時,它也是各種編程語言對於開發者最明顯的差異化特徵。一個有經驗的開發者可以很容易地通過掃視一段代碼,就能分辨出這是哪種編程語言編寫的計算機程序。
編程語言的語義描述了一段符合語言語法的程序,對於計算機而言的真正含義,是開發者最終要傳達給計算機的意願和指令。語言的語義必須是准確的、無二義性的,編譯器也正是通過語義的指導,將計算機程序翻譯為計算機可識別的表達形式。

三、程序的翻譯
計算機程序是用來供人閱讀和修改的,計算機硬體並不能理解程序內的思想和含義。因此,必須有一個翻譯轉換的過程,將人所表達的意願准確無誤地傳遞給計算機,讓計算機明確並執行人下發的指令。實現這種翻譯工作的工具就是編譯器或解釋器。
對於編譯器來說,它的輸入是人類書寫的計算機語言程序,輸出則是計算機可識別的底層表示。首先,它需要識別出程序中的單詞,即詞法分析。然後,根據單詞的組合模式識別出程序的語法結構,即語法分析。最後,根據不同的語法結構對應的語義,將程序按照每個語法模塊的形式轉換為計算機可識別的指令序列,即語義分析和目標代碼生成。
眾所周知編譯器的實現具有一定的復雜度,其根本原因來自於語言語法的結構靈活性和計算機底層表達形式的多樣性,這也是創造一門編程語言最核心的環節。

四、二進制存儲
編譯器將語言程序翻譯轉換後,需要將轉換後的結果存儲起來,以便計算機在需要的時候將其載入、執行。這里不可避免的涉及到兩個問題:
(1)轉換後的結果是什麼樣的形式?
(2)轉換後的結果保存在哪裡?
第一個問題描述的是計算機程序被轉換為怎樣的形式,才是計算機可以識別的。由於計算機中實際運行程序的硬體模塊是CPU,因此計算機程序只有被轉換為CPU的二進制指令格式才能被正確識別、執行。比如常見的Intel體系的CISC指令格式、ARM體系的RISC執行格式等。
第二個問題描述的是計算機程序轉化為二進制指令格式後,以什麼樣的方式保存在計算機的磁碟上。由於絕大多數的計算機程序是需要通過運行在計算機硬體之上的操作系統載入運行的,因此計算機程序的二進製表達形式必須以對應操作系統可識別的文件格式存儲。比如常見的Windows操作系統的PE文件格式、Linux操作系統的ELF文件格式等。

五、運行時環境和標准庫
理論上講,一門編程語言如果能提供出完備的操縱操作系統和硬體的原子性功能就已經成功了。但是不提供強大的運行時環境支持和標准庫,是很難讓一門編程語言真正的好用和流行的。沒有人希望簡單地列印一行字元串,還需要使用編程語言提供的基本特性實現調用操作系統提供的列印介面的邏輯。Java語言之所以久興不衰,正是因為它不僅提供了完善的運行時環境和開發庫支持,甚至提供了更強大的開發框架和工具支持。
因此可見,除了完備的語言特性,為開發者提供更方便好用的庫和框架支持,消除軟體構建過程中復雜和重復的邏輯,才是一門優秀編程語言的長盛之道。

六、自己動手,立即開始!
《自己動手構造編譯系統——編譯、匯編與鏈接》一書詳細闡述了一門編程語言從無到有的過程,從語言的功能特性設計,到詞法、文法、語義分析;從編譯器、匯編器的設計實現,到目標文件的鏈接生成可執行文件;甚至編譯優化器的實現、二進制指令、可執行文件格式以及語言運行時和標准庫的概念,都在書中做了認真細致地剖析。相信對本書的閱讀,將是一次不錯的獲得知識的體驗!

閱讀全文

與如何創造一門語言相關的資料

熱點內容
馬鞍山ok論壇怎麼刪除帖子 瀏覽:242
馬鞍山恆生陽光集團 瀏覽:235
麻城工商局領導成員 瀏覽:52
鄉級公共衛生服務績效考核方案 瀏覽:310
樂聚投訴 瀏覽:523
輪子什麼時候發明 瀏覽:151
馬鞍山陶世宏 瀏覽:16
馬鞍山茂 瀏覽:5
通遼工商局咨詢電話 瀏覽:304
誰發明的糍粑 瀏覽:430
國家公共文化服務示範區 瀏覽:646
pdf設置有效期 瀏覽:634
廣告詞版權登記 瀏覽:796
基本公共衛生服務考核方案 瀏覽:660
公共服務平台建設領導小組 瀏覽:165
人類創造了那些機器人 瀏覽:933
公共文化服務保障法何時實施 瀏覽:169
遼寧育嬰師證書領取 瀏覽:735
劃撥土地使用權轉讓能轉讓嗎 瀏覽:97
2019年公需科目知識產權考試答案 瀏覽:256