我跟你說,編譯原理太有用了。
我是做手機游戲的,現在做一個游戲引擎。既然是引擎,就需要提供抽象的東西給上層使用。這里,我引入了腳本系統。
這個腳本系統包括一堆我根據實際需求自行設計的指令集,包括基本的輸入輸出,四則運算,系統功能調用,函數聲明,調用等等(其實你要是用過lua或者其他游戲腳本你就知道了。)整個結構包括指令集、編譯器、虛擬機等部分。這樣,引擎提供一些基礎服務,比如繪圖,計算位置等,腳本就可以非常簡單控制游戲。甚至快速構建新游戲。你應該知道QUAKE引擎吧?
這里提供給你一個計算器的小程序,應用了EBNF理論,支持表達式,比如(2+3*6)*4+4,你自己體驗一下它的簡潔和強大。
/*
simple integer arithmetic calculator according to the EBNF
<exp> -> <term>{<addop><term>}
<addop>->+|-
<term>-><factor>{<mulop><factor>}
<mulop> -> *
<factor> -> ( <exp> )| Number
Input a line of text from stdin
Outputs "Error" or the result.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char token;/*global token variable*/
/*function prototypes for recursive calls*/
int exp(void);
int term(void);
int factor(void);
void error(void)
{
fprintf(stderr,"Error\n");
exit(1);
}
void match(char expectedToken)
{
if(token==expectedToken)token=getchar();
else error();
}
main()
{
int result;
token = getchar();/*load token with first character for lookahead*/
result = exp();
if(token=='\n')/*check for end of line */
printf("Result = %d\n",result);
else error();/*extraneous cahrs on line*/
return 0;
}
int exp(void)
{
int temp = term();
while((token=='+')||(token=='-'))
switch(token)
{
case '+':
match('+');
temp+=term();
break;
case '-':
match('-');
temp-=term();
break;
}
return temp;
}
int term(void)
{
int temp = factor();
while (token=='*')
{
match('*');
temp*=factor();
}
return temp;
}
int factor(void)
{
int temp;
if(token=='('){
match('(');
temp = exp();
match(')');
}
else if(isdigit(token)){
ungetc(token,stdin);
scanf("%d",&temp);
token = getchar();
}
else error();
return temp;
}
其實編程學到一定程度總是沒有方向了,總是在問學C/C++下一步怎麼學啊,覺得掌握了該語言了雲雲,實際上,你缺少的就是這些軟的東西,缺少的是理論。
編譯原理不是單一的理論,它涵蓋了一個niche,裡面可以學到很多其他知識,比如正則表達式、BNF、EBNF、分析樹、語法樹還有很多運行時環境等知識
這些給你帶來的是非常豐厚的回報。不說多了,學完運行時,你就會加深對C++語言本身的理解。
你要想有好的發展,還是學吧。
Ⅱ 編譯原理除了可以用來編寫編譯器,還在哪些領域可以用到編譯原理的知識
很多的,例如MASM編譯器。
編譯原理內容包括語言和文法、詞法分析、語法分析、語法制導翻譯、中間代碼生成、存儲管理、代碼優化和目標代碼生成等,這門課大部分人聽起來比較困難,介紹編譯程序構造的一般原理和基本方法,雖然只有少數人從事編譯方面的工作,但是這門課在理論、技術、方法上都對我們提供了系統而有效的訓練,有利於提高軟體人員的素質和能力。
Ⅲ 一個編譯程序有幾部分構成
作為一個功能完整、且強大的編譯器,一般來說包括如下幾個部分:詞法分析、語法分析、語義分析(因為語法上正確的,但是語義不一定正確。例如:老虎吃人、人吃老虎,語法是正確的,都是主謂賓格式,且詞性相同,但是從語義分析上講就是錯誤的)、中間代碼生成、直到生成可執行程序。
Ⅳ 一個編譯器至少包含三個部分的進程是什麼
一個典型的編譯程序通常包含8個組成部分,它們是詞法分析程序、語法分析程序、語義分析程序、中間代碼生成程序、中間代碼優化程序、目標代碼生成程序、表格管理程序和錯誤處理程序。
(1) 編譯程序:如果源語言為高級語言,目標語言為某台計算機上的匯編語言或機器語
言,則此翻譯程序稱為編譯程序。
(2) 源程序:源語言編寫的程序稱為源程序。
(3) 目標程序:目標語言書寫的程序稱為目標程序。
(4) 編譯程序的前端:它由這樣一些階段組成:這些階段的工作主要依賴於源語言而與
目標機無關。通常前端包括詞法分析、語法分析、語義分析和中間代碼生成這些階
段,某些優化工作也可在前端做,也包括與前端每個階段相關的出錯處理工作和符
號表管理等工作。
(5) 後端:指那些依賴於目標機而一般不依賴源語言,只與中間代碼有關的那些階段,
即目標代碼生成,以及相關出錯處理和符號表操作。
(6) 遍:是對源程序或其等價的中間語言程序從頭到尾掃視並完成規定任務的過程。
詞法分析程序:輸人源程序,拼單詞、檢查單詞和分析單詞,輸出單詞的機內表達形式。
語法分析程序:檢查源程序中存在的形式語法錯誤,輸出錯誤處理信息。
語義分析程序:進行語義檢查和分析語義信息,並把分析的結果保存到各類語義信息表中。
中間代碼生成程序:按照語義規則,將語法分析程序分析出的語法單位轉換成一定形式的中間語言代碼,如三元式或四元式。
中間代碼優化程序:為了產生高質量的目標代碼,對中間代碼進行等價變換處理
Ⅳ 典型的編譯器可以劃分成幾個主要的邏輯階段
這是我們今天的作業,
典型的編譯器可以劃分成七個主要的邏輯階段,分別是詞法分析器、語法分析器、語義分析器、中間代碼生成器、獨立於機器的代碼優化器、代碼生成器、依賴於機器的代碼優化器。各階段的主要功能:
(1)詞法分析器:詞法分析閱讀構成源程序的字元流,按編程語言的詞法規則把它們組成詞法記號流。
(2)語法分析器:按編程語言的語法規則檢查詞法分析輸出的記號流是否符合這些規則,並依據這些規則所體現出的該語言的各種語言構造的層次性,用各記號的第一元建成一種樹形的中間表示,這個中間表示用抽象語法的方式描繪了該記號流的語法情況。
(3)語義分析器:使用語法樹和符號表中的信息,依據語言定義來檢查源程序的語義一致性,以保證程序各部分能有意義地結合在一起。它還收集類型信息,把它們保存在符號表或語法樹中。
(4)中間代碼生成器:為源程序產生更低級的顯示中間表示,可以認為這種中間表示是一種抽象機的程序。
(5)獨立於機器的代碼優化器:試圖改進中間代碼,以便產生較好的目標代碼。通常,較好是指執行較快,但也可能是其他目標,如目標代碼較短或目標代碼執行時能耗較低。
(6)代碼生成器:取源程序的一種中間表示作為輸入並把它映射到一種目標語言。如果目標語言是機器代碼,則需要為源程序所用的變數選擇寄存器或內存單元,然後把中間指令序列翻譯為完成同樣任務的機器指令序列。
(7)依賴於機器的代碼優化器:試圖改進目標機器代碼,以便產生較好的目標機器代碼。
Ⅵ 北大青鳥設計培訓:編程需要多少數學知識
1、編程中的數學於是我馬上回顧了下編程中用到的數學知識,好像少的可憐。
計數的能力:for循環中經常用,小學生都會。
數字的加減乘除:每種編程語言都會內置支持,都不需要你自己算余數和模:偶爾會用得到集合運算:交集、並集、差集,編程中用的不多。
布爾運算:AND,OR,非各種進制:二進制、十進制、十六進制還有哪些?我想不起來了。
當然這和我從事的編程領域有極大關系,廣州北大青鳥http://www.kmbdqn.cn/認為如果我做的不是Web開發,而是搜索,游戲,安全,演算法,人工智慧等,那對數學的要求估計就開始飆升了。
其實計算機的基礎是數學,只是我們一直在應用層編程,體會不到罷了。
比如說我們日常使用的計算機,絕大部分都是所謂馮諾依曼結構,這個結構可以說是圖靈機這個概念機器的具體實現,而圖靈機就是一個純數學的東西啊,沒有圖靈機這么偉大的抽象作為數學基礎,現代的計算機是製造不出來的。
再比如說密碼領域需要很多數論的知識,RSA演算法就涉及到大素數的分解;我們常用的Mysql,Oracle等關系資料庫的底層基礎是離散數學的笛卡爾乘積;通信系統中很重要的一個原理就是傅里葉變換。
編譯器會用到有限狀態機;數據的壓縮會用到各種數學的演算法;項目管理中的進度管理,甘特圖數學基礎就是圖論。
.....總之,數學在計算機科學扮演著非常重要的角色,是整個學科的基礎。
2、不拼數學拼什麼?具體到應用層編程,尤其Web開發、企業信息化開發,整天折騰的是框架和類庫,用不到這么多高大上的數學知識,那到底拼的是什麼?想想編程中常用的數組,如果是一維數組,做個循環和遍歷,每個人都能輕松應對。
如果要用數組來表示二叉樹,就需要把一個樹形結構對應到線性結構,那難度立刻上升。
如果在編程中需要自己實現鏈表,就會發現把各個節點的鏈接關系維護好,需要把指針調來調去,挪來挪去,實在不是一件容易的事情。
這樣的能力就是邏輯思維的一種體現。
我們在做系統設計的時候,經常需要總結、分析現實需求,找到容易變化的部分和相對穩定的部分,把他們封裝起來,形成核心的概念,支撐起整個系統,這是一個抽象的過程,雖然用不到多少數學知識,但是思維的過程也極不容易。
邏輯思維能力和抽象能力的差別,能夠區分出程序員的優秀和平庸。
一個優秀程序員寫出的代碼,介面清晰,容易擴展,易於維護;一個差程序員寫出的代碼,思路混亂,完全是一些計算機語句的堆砌,別人看不明白,過一段時間自己都看不明白了。
數學系的同學在這兩方面恰恰是長項,想想看,數學系同學們整天折騰這么多「枯燥的」抽象概念,再去看編程這樣大部分都是具體化的實現,簡直是分分鍾搞定!這可能是數學系的轉到編程領域很厲害的原因吧。
邏輯思維能力通過學習數據結構和演算法,做數據結構的習題可以得到有效的提高,抽象能力需要在實踐中不斷的練習、積累經驗。
對於初學編程的同學,從現在就開始努力提升吧!
Ⅶ 編譯器的工作分為哪幾個階段
編譯器就是一個普通程序,沒什麼大不了的
什麼是編譯器?
編譯器是一個將高級語言翻譯為低級語言的程序。
首先我們一定要意識到編譯器就是一個普通程序,沒什麼大不了的。
在沒有弄明白編譯器如何工作之前你可以簡單的把編譯器當做一個黑盒子,其作用就是輸入一個文本文件輸出一個二進制文件。
基本上編譯器經過了以下幾個階段,等等,這句話教科書上也有,但是我相信很多同學其實並沒有真正理解這幾個步驟到底在說些什麼,為了讓你徹底理解這幾個步驟,我們用一個簡單的例子來講解。
假定我們有一段程序:
while (y < z) {
int x = a + b;
y += x;
}
那麼編譯器是怎樣把這一段程序人類認識的程序轉換為CPU認識的二進制機器指令呢?
提取出每一個單詞:詞法分析
首先編譯器要把源代碼中的每個「單詞」提取出來,在編譯技術中「單詞」被稱為token。其實不只是每個單詞被稱為一個token,除去單詞之外的比如左括弧、右括弧、賦值操作符等都被稱為token。
從源代碼中提取出token的過程就被稱為詞法分析,Lexical Analysis。
經過一遍詞法分析,編譯器得到了以下token:
T_While while
T_LeftParen (
T_Identifier y
T_Less <
T_Identifier z
T_RightParen )
T_OpenBrace {
T_Int int
T_Identifier x
T_Assign =
T_Identifier a
T_Plus +
T_Identifier b
T_Semicolon ;
T_Identifier y
T_PlusAssign +=
T_Identifier x
T_Semicolon ;
T_CloseBrace }
就這樣一個磁碟中保存的字元串源代碼文件就轉換為了一個個的token。
這些token想表達什麼意思:語法分析
有了這些token之後編譯器就可以根據語言定義的語法恢復其原本的結構,怎麼恢復呢?
原來,編譯器在掃描出各個token後根據規則將其用樹的形式表示出來,這顆樹就被稱為語法樹。
語法樹是不是合理的:語義分析
有了語法樹後我們還要檢查這棵樹是不是合法的,比如我們不能把一個整數和一個字元串相加、比較符左右兩邊的數據類型要相同,等等。
這一步通過後就證明了程序合法,不會有編譯錯誤。
Ⅷ 典型的編譯器可以劃分成幾個邏輯階段
這是我們今天的作業,
典型的編譯器可以劃分成七個主要的邏輯階段,分別是詞法分析器、語法分析器、語義分析器、中間代碼生成器、獨立於機器的代碼優化器、代碼生成器、依賴於機器的代碼優化器。各階段的主要功能:
(1)詞法分析器:詞法分析閱讀構成源程序的字元流,按編程語言的詞法規則把它們組成詞法記號流。
(2)語法分析器:按編程語言的語法規則檢查詞法分析輸出的記號流是否符合這些規則,並依據這些規則所體現出的該語言的各種語言構造的層次性,用各記號的第一元建成一種樹形的中間表示,這個中間表示用抽象語法的方式描繪了該記號流的語法情況。
(3)語義分析器:使用語法樹和符號表中的信息,依據語言定義來檢查源程序的語義一致性,以保證程序各部分能有意義地結合在一起。它還收集類型信息,把它們保存在符號表或語法樹中。
(4)中間代碼生成器:為源程序產生更低級的顯示中間表示,可以認為這種中間表示是一種抽象機的程序。
(5)獨立於機器的代碼優化器:試圖改進中間代碼,以便產生較好的目標代碼。通常,較好是指執行較快,但也可能是其他目標,如目標代碼較短或目標代碼執行時能耗較低。
(6)代碼生成器:取源程序的一種中間表示作為輸入並把它映射到一種目標語言。如果目標語言是機器代碼,則需要為源程序所用的變數選擇寄存器或內存單元,然後把中間指令序列翻譯為完成同樣任務的機器指令序列。
(7)依賴於機器的代碼優化器:試圖改進目標機器代碼,以便產生較好的目標機器代碼。
Ⅸ 一個類C的編譯器大概有多少行
很難說確定多少行的,代碼的多少要看演算法和實現。反正我為了實現一個子集花了三四千行,太累了,但是網上JIT C 編譯器,確僅僅575 行。