① 編譯原理:詞法分析中,token 為什麼要長度統一
每一個token都是從源文本中讀取的符合詞法規則的單詞。比如,有文本:
I love you,詞法為:I | love | you,則經分析將分別獲得tokens:I,love,you。token需要長度統一嗎?我認為不需要,從來都不需要,不知你從哪獲得的知識,也許是個誤會吧。
② 編譯原理的最左推導和最右推導問題
最左推導:
S=> (L) =>(L,S)=>(S,S)=>(a,S)=>(a,(L))=>(a,(L,S))=>(a,(S,S))=>(a,((L),S))=>(a,((L,S),S))
=>(a,((S,S),S))=>(a,((a,S),S))=>(a,((a,a),S))=>(a,((a,a),(L)))=>(a,((a,a),(L,S)))
=>(a,((a,a),(S,S)))=>(a,((a,a),(a,S)))=>(a,((a,a),(a,a))) 共17步
最右推導
S=> (L) =>(L,S)=>(L,(L))=>(L,(L,S))=>(L,(L,(L)))=>(L,(L,(L,S)))=>(L,(L,(L,a)))=>(L,(L,(S,a)))
=>(L,(L,(a,a)))=>(L,(S,(a,a)))=>(L,((L),(a,a)))=>(L,((L,S),(a,a)))=>(L,((L,a),(a,a)))
=>(L,((S,a),(a,a)))=>(L,((a,a),(a,a)))=>(S,((a,a),(a,a)))=>(a,((a,a),(a,a)))
③ 編譯原理的最左推導和最右推導。。。
(2)給出句子0127,34和568的最左推導和最右推導我是剛學編譯原理,不知道該怎麼去思考,從那入手呢? (1)帶先導0的十進制無符號整數 (2)最左推導:
④ 關於編譯原理中的最右推導問題。題目如下:
大寫A應該是最右邊的非終結符號,S怎麼是最右非終結符號?最右推導是將最右邊的非終結符號替換
⑤ 編譯原理最左最右推導規則
因為推導過程並不要求所有的產生式都用上。再給你舉個例子,比如:
baa,那推導也是S=>AB=>bBB=>baB=>baa,也沒有用到那個式子啊。
當然,有可能這個式子永遠用不到,也就是這個式子的功能可以用另外的式子替換,這時候,這個文法就是有冗餘的。
⑥ 編譯原理試題·
Lex和Yacc應用方法(一).初識Lex
草木瓜 20070301
Lex(Lexical Analyzar 詞法分析生成器),Yacc(Yet Another Compiler Compiler
編譯器代碼生成器)是Unix下十分重要的詞法分析,語法分析的工具。經常用於語言分
析,公式編譯等廣泛領域。遺憾的是網上中文資料介紹不是過於簡單,就是跳躍太大,
入門參考意義並不大。本文通過循序漸進的例子,從0開始了解掌握Lex和Yacc的用法。
一.Lex(Lexical Analyzar) 初步示例
先看簡單的例子(註:本文所有實例皆在RetHat linux下完成):
一個簡單的Lex文件 exfirst.l 內容:
%{
#include "stdio.h"
%}
%%
[\n] ;
[0-9]+ printf("Int : %s\n",yytext);
[0-9]*\.[0-9]+ printf("Float : %s\n",yytext);
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);
[\+\-\*\/\%] printf("Op : %s\n",yytext);
. printf("Unknown : %c\n",yytext[0]);
%%
在命令行下執行命令flex解析,會自動生成lex.yy.c文件:
[root@localhost liweitest]flex exfirst.l
進行編譯生成parser可執行程序:
[root@localhost liweitest]cc -o parser lex.yy.c -ll
[注意:如果不加-ll鏈結選項,cc編譯時會出現以下錯誤,後面會進一步說明。]
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crt1.o(.text+0x18): In function `_start':
../sysdeps/i386/elf/start.S:77: undefined reference to `main'
/tmp/cciACkbX.o(.text+0x37b): In function `yylex':
: undefined reference to `yywrap'
/tmp/cciACkbX.o(.text+0xabd): In function `input':
: undefined reference to `yywrap'
collect2: ld returned 1 exit status
創建待解析的文件 file.txt:
title
i=1+3.9;
a3=909/6
bcd=4%9-333
通過已生成的可執行程序,進行文件解析。
[root@localhost liweitest]# ./parser < file.txt
Var : title
Var : i
Unknown : =
Int : 1
Op : +
Float : 3.9
Unknown : ;
Var : a3
Unknown : =
Int : 909
Op : /
Int : 6
Var : bcd
Unknown : =
Int : 4
Op : %
Int : 9
Op : -
Int : 333
到此Lex用法會有個直觀的了解:
1.定義Lex描述文件
2.通過lex,flex工具解析成lex.yy.c文件
3.使用cc編譯lex.yy.c生成可執行程序
再來看一個比較完整的Lex描述文件 exsec.l :
%{
#include "stdio.h"
int linenum;
%}
%%
title showtitle();
[\n] linenum++;
[0-9]+ printf("Int : %s\n",yytext);
[0-9]*\.[0-9]+ printf("Float : %s\n",yytext);
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);
[\+\-\*\/\%] printf("Op : %s\n",yytext);
. printf("Unknown : %c\n",yytext[0]);
%%
showtitle()
{
printf("----- Lex Example -----\n");
}
int main()
{
linenum=0;
yylex(); /* 進行分析 */
printf("\nLine Count: %d\n",linenum);
return 0;
}
int yywrap()
{
return 1;
}
進行解析編譯:
[root@localhost liweitest]flex exsec.l
[root@localhost liweitest]cc -o parser lex.yy.c
[root@localhost liweitest]./parser < file.txt
----- Lex Example -----
Var : i
Unknown : =
Int : 1
Op : +
Float : 3.9
Unknown : ;
Var : a3
Unknown : =
Int : 909
Op : /
Int : 6
Var : bcd
Unknown : =
Int : 4
Op : %
Int : 9
Op : -
Int : 333
Line Count: 4
這里就沒有加-ll選項,但是可以編譯通過。下面開始著重整理下Lex描述文件.l。
二.Lex(Lexical Analyzar) 描述文件的結構介紹
Lex工具是一種詞法分析程序生成器,它可以根據詞法規則說明書的要求來生成單詞識
別程序,由該程序識別出輸入文本中的各個單詞。一般可以分為<定義部分><規則部
分><用戶子程序部分>。其中規則部分是必須的,定義和用戶子程序部分是任選的。
(1)定義部分
定義部分起始於 %{ 符號,終止於 %} 符號,其間可以是包括include語句、聲明語句
在內的C語句。這部分跟普通C程序開頭沒什麼區別。
%{
#include "stdio.h"
int linenum;
%}
(2) 規則部分
規則部分起始於"%%"符號,終止於"%%"符號,其間則是詞法規則。詞法規則由模式和
動作兩部分組成。模式部分可以由任意的正則表達式組成,動作部分是由C語言語句組
成,這些語句用來對所匹配的模式進行相應處理。需要注意的是,lex將識別出來的單
詞存放在yytext[]字元數據中,因此該數組的內容就代表了所識別出來的單詞的內容。
類似yytext這些預定義的變數函數會隨著後面內容展開一一介紹。動作部分如果有多
行執行語句,也可以用{}括起來。
%%
title showtitle();
[\n] linenum++;
[0-9]+ printf("Int : %s\n",yytext);
[0-9]*\.[0-9]+ printf("Float : %s\n",yytext);
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);
[\+\-\*\/\%] printf("Op : %s\n",yytext);
. printf("Unknown : %c\n",yytext[0]);
%%
A.規則部分的正則表達式
規則部分是Lex描述文件中最為復雜的一部分,下面列出一些模式部分的正則表達式字
符含義:
A-Z, 0-9, a-z 構成模式部分的字元和數字。
- 指定范圍。例如:a-z 指從 a 到 z 之間的所有字元。
\ 轉義元字元。用來覆蓋字元在此表達式中定義的特殊意義,
只取字元的本身。
[] 表示一個字元集合。匹配括弧內的任意字元。如果第一個字
符是^那麼它表示否定模式。例如: [abC] 匹配 a, b, 和C
的任何一個。
^ 表示否定。
* 匹配0個或者多個上述模式。
+ 匹配1個或者多個上述模式。
? 匹配0個或1個上述模式。
$ 作為模式的最後一個字元時匹配一行的結尾。
{ } 表示一個模式可能出現的次數。 例如: A{1,3} 表示 A 可
能出現1次或3次。[a-z]{5} 表示長度為5的,由a-z組成的
字元。此外,還可以表示預定義的變數。
. 匹配任意字元,除了 \n。
( ) 將一系列常規表達式分組。如:{Letter}({Letter}|{Digit})*
| 表達式間的邏輯或。
"一些符號" 字元的字面含義。元字元具有。如:"*" 相當於 [\*]。
/ 向前匹配。如果在匹配的模式中的"/"後跟有後續表達式,
只匹配模版中"/"前面的部分。如:模式為 ABC/D 輸入 ABCD,
時ABC會匹配ABC/D,而D會匹配相應的模式。輸入ABCE的話,
ABCE就不會去匹配ABC/D。
B.規則部分的優先順序
規則部分具有優先順序的概念,先舉個簡單的例子:
%{
#include "stdio.h"
%}
%%
[\n] ;
A {printf("ONE\n");};
AA {printf("TWO\n");};
AAAA {printf("THREE\n");};
%%
此時,如果輸入內容:
[root@localhost liweitest]# cat file1.txt
AAAAAAA
[root@localhost liweitest]# ./parser < file1.txt
THREE
TWO
ONE
Lex分析詞法時,是逐個字元進行讀取,自上而下進行規則匹配的,讀取到第一個A字元
時,遍歷後發現三個規則皆匹配成功,Lex會繼續分析下去,讀至第五個字元時,發現
"AAAA"只有一個規則可用,即按行為進行處理,以此類推。可見Lex會選擇最長的字元
匹配規則。
如果將規則
AAAA {printf("THREE\n");};
改為
AAAAA {printf("THREE\n");};
./parser < file1.txt 輸出結果為:
THREE
TWO
再來一個特殊的例子:
%%
title showtitle();
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);
%%
並輸入title,Lex解析完後發現,仍然存在兩個規則,這時Lex只會選擇第一個規則,下面
的則被忽略的。這里就體現了Lex的順序優先順序。把這個例子稍微改一下:
%%
[a-zA-Z][a-zA-Z0-9]* printf("Var : %s\n",yytext);
title showtitle();
%%
Lex編譯時會提示:warning, rule cannot be matched.這時處理title字元時,匹配
到第一個規則後,第二個規則就無效了。
再把剛才第一個例子修改下,加深下印象!
%{
#include "stdio.h"
%}
%%
[\n] ;
A {printf("ONE\n");};
AA {printf("TWO\n");};
AAAA {printf("THREE\n");};
AAAA {printf("Cannot be executed!");};
./parser < file1.txt 顯示效果是一樣的,最後一項規則肯定是會忽略掉的。
C.規則部分的使用變數
且看下面示例:
%{
#include "stdio.h"
int linenum;
%}
int [0-9]+
float [0-9]*\.[0-9]+
%%
{int} printf("Int : %s\n",yytext);
{float} printf("Float : %s\n",yytext);
. printf("Unknown : %c\n",yytext[0]);
%%
在%}和%%之間,加入了一些類似變數的東西,注意是沒有;的,這表示int,float分
別代指特定的含義,在兩個%%之間,可以通過{int}{float}進行直接引用,簡化模
式定義。
(3) 用戶子程序部分
最後一個%%後面的內容是用戶子程序部分,可以包含用C語言編寫的子程序,而這些子
程序可以用在前面的動作中,這樣就可以達到簡化編程的目的。這里需要注意的是,
當編譯時不帶-ll選項時,是必須加入main函數和yywrap(yywrap將下後面說明)。如:
...
%%
showtitle()
{
printf("----- Lex Example -----\n");
}
int main()
{
linenum=0;
yylex(); /* 進行Lex分析 */
printf("\nLine Count: %d\n",linenum);
return 0;
}
int yywrap()
{
return 1;
}
三.Lex(Lexical Analyzar) 一些的內部變數和函數
內部預定義變數:
yytext char * 當前匹配的字元串
yyleng int 當前匹配的字元串長度
yyin FILE * lex當前的解析文件,默認為標准輸出
yyout FILE * lex解析後的輸出文件,默認為標准輸入
yylineno int 當前的行數信息
內部預定義宏:
ECHO #define ECHO fwrite(yytext, yyleng, 1, yyout) 也是未匹配字元的
默認動作
內部預定義的函數:
int yylex(void) 調用Lex進行詞法分析
int yywrap(void) 在文件(或輸入)的末尾調用。如果函數的返回值是1,就停止解
析。 因此它可以用來解析多個文件。代碼可以寫在第三段,這
樣可以解析多個文件。 方法是使用 yyin 文件指針指向不同的
文件,直到所有的文件都被解析。最後,yywrap() 可以返回1
來表示解析的結束。
lex和flex都是解析Lex文件的工具,用法相近,flex意為fast lexical analyzer generator。
可以看成lex的升級版本。
相關更多內容就需要參考flex的man手冊了,十分詳盡。
四.關於Lex的一些綜述
Lex其實就是詞法分析器,通過配置文件*.l,依據正則表達式逐字元去順序解析文件,
並動態更新內存的數據解析狀態。不過Lex只有狀態和狀態轉換能力。因為它沒有堆棧,
它不適合用於剖析外殼結構。而yacc增加了一個堆棧,並且能夠輕易處理像括弧這樣的
結構。Lex善長於模式匹配,如果有更多的運算要求就需要yacc了。
⑦ 處理器的發展具體什麼情況怎麼一看就知道處理器的情況啊
心問題--從數學談起:
記得當年大一入學,每周六課時高等數學,天天作業不斷(那時是六日工作制)。頗有些同學驚呼走錯了門:咱們這到底念的是什麼系?不錯,你沒走錯門,這就是計算機科學與技術系。我國計算機科學系裡的傳統是培養做學術研究,尤其是理論研究的人(方向不見得有問題,但是做得不是那麼盡如人意)。而計算機的理論研究,說到底了,如網路安全,圖形圖像學,視頻音頻處理,哪個方向都與數學有著很大的關系,雖然也許是正統數學家眼裡非主流的數學。這里我還想闡明我的一個觀點:我們都知道,數學是從實際生活當中抽象出來的理論,人們之所以要將實際抽象成理論,目的就在於想用抽象出來的理論去更好的指導實踐,有些數學研究工作者喜歡用一些現存的理論知識去推導若干條推論,殊不知其一:問題考慮不全很可能是個錯誤的推論,其二:他的推論在現實生活中找不到原型,不能指導實踐。嚴格的說,我並不是一個理想主義者,政治課上學的理論聯系實際一直是指導我學習科學文化知識的航標(至少我認為搞計算機科學與技術的應當本著這個方向)。
其實我們計算機系學數學光學高等數學是不夠的(典型的工科院校一般都開的是高等數學),我們應該像數學系一樣學一下數學分析(清華計算機系開的好像就是數學分析),數學分析這門科學,咱們學計算機的人對它有很復雜的感情。在於它是偏向於證明型的數學課程,這對我們培養良好的分析能力極有幫助。我的軟體工程學導師北工大數理學院的王儀華先生就曾經教導過我們,數學系的學生到軟體企業中大多作軟體設計與分析工作,而計算機系的學生做程序員的居多,原因就在於數學系的學生分析推理能力,從所受訓練的角度上要遠遠在我們之上。當年出現的怪現象是:計算機系學生的高中數學基礎在全校數一數二(希望沒有冒犯其它系的同學),教學課時數也僅次於數學系,但學完之後的效果卻不盡如人意。難道都是學生不努力嗎,我看未見得,方向錯了也說不一定,其中原因何在,發人深思。
我個人的淺見是:計算機系的學生,對數學的要求固然跟數學系不同,跟物理類差別則更大。通常非數學專業的所謂「高等數學」,無非是把數學分析中較困難的理論部分刪去,強調套用公式計算而已。而對計算機系來說,數學分析里用處最大的恰恰是被刪去的理論部分。說得難聽一點,對計算機系學生而言,追求算來算去的所謂「工程數學」已經徹底地走進了誤區。記上一堆曲面積分的公式,難道就能算懂了數學?那倒不如現用現查,何必費事記呢?再不然直接用Mathematics或是Matalab好了。
我在系裡最愛做的事情就是給學弟學妹們推薦參考書。中文的數學分析書,一般都認為以北大張築生老師的「數學分析新講」為最好。萬一你的數學實在太好,那就去看菲赫金哥爾茨的「微積分學教程」好了--但我認為沒什麼必要,畢竟你不想轉到數學系去。吉米多維奇的「數學分析習題集」也基本上是計算型的東東。書的名氣很大,倒不見得適合我們,還是那句話,重要的是數學思想的建立,生活在信息社會里我們求的是高效,計算這玩意還是留給計算機吧。不過現在多用的似乎是復旦大學的《數學分析》也是很好的教材。
中國的所謂高等代數,就等於線性代數加上一點多項式理論。我以為這有好的一面,因為可以讓學生較早感覺到代數是一種結構,而非一堆矩陣翻來覆去。這里不得不提南京大學林成森,盛松柏兩位老師編的「高等代數」,感覺相當舒服。此書相當全面地包含了關於多項式和線性代數的基本初等結果,同時還提供了一些有用的又比較深刻的內容,如Sturm序列,Shermon-Morrison公式,廣義逆矩陣等等。可以說,作為本科生如能吃透此書,就可以算高手。國內較好的高等代數教材還有清華計算機系用的那本,清華出版社出版,書店裡多多,一看就知道。從抽象代數的觀點來看,高等代數里的結果不過是代數系統性質的一些例子而已。莫宗堅先生的《代數學》里,對此進行了深刻的討論。然而莫先生的書實在深得很,作為本科生恐怕難以接受,不妨等到自己以後成熟了一些再讀。
正如上面所論述的,計算機系的學生學習高等數學:知其然更要知其所以然。你學習的目的應該是:將抽象的理論再應用於實踐,不但要掌握題目的解題方法,更要掌握解題思想,對於定理的學習:不是簡單的應用,而是掌握證明過程即掌握定理的由來,訓練自己的推理能力。只有這樣才達到了學習這門科學的目的,同時也縮小了我們與數學系的同學之間思維上的差距。
概率論與數理統計這門課很重要,可惜大多數院校講授這門課都會少些東西。少了的東西現在看至少有隨機過程。到畢業還沒有聽說過Markov過程,此乃計算機系學生的恥辱。沒有隨機過程,你怎麼分析網路和分布式系統?怎麼設計隨機化演算法和協議?據說清華計算機系開有「隨機數學」,早就是必修課。另外,離散概率論對計算機系學生來說有特殊的重要性。而我們國家工程數學講的都是連續概率。現在,美國已經有些學校開設了單純的「離散概率論」課程,乾脆把連續概率刪去,把離散概率講深些。我們不一定要這么做,但應該更加強調離散概率是沒有疑問的。這個工作我看還是盡早的做為好。
計算方法學(有些學校也稱為數學分析學)是最後一門由數理學院給我們開的課。一般學生對這門課的重視程度有限,以為沒什麼用。不就是照套公式嘛!其實,做圖形圖像可離不開它,密碼學搞深了也離不開它。而且,在很多科學工程中的應用計算,都以數值的為主。這門課有兩個極端的講法:一個是古典的「數值分析」,完全講數學原理和演算法;另一個是現在日趨流行的「科學與工程計算」,乾脆教學生用軟體包編程。我個人認為,計算機系的學生一定要認識清楚我們計算機系的學生為什麼要學這門課,我是很偏向於學好理論後用計算機實現的,最好使用C語言或C++編程實現。向這個方向努力的書籍還是挺多的,這里推薦大家高等教育出版社(CHEP)和施普林格出版社(Springer)聯合出版的《計算方法(Computational Methods)》,華中理工大學數學系寫的(現華中科技大學),這方面華科大做的工作在國內應算是比較多的,而個人認為以這本最好,至少程序設計方面涉及了:任意數學函數的求值,方程求根,線性方程組求解,插值方法,數值積分,場微分方程數值求解。李慶揚的那本則理論性過強,與實際應用結合得不太緊。
每個學校本系裡都會開一門離散數學,涉及集合論,圖論,和抽象代數,數理邏輯。不過,這么多內容擠在離散數學一門課里,是否時間太緊了點?另外,計算機系學生不懂組合和數論,也是巨大的缺陷。要做理論,不懂組合或者數論吃虧可就太大了。從理想的狀態來看,最好分開六門課:集合,邏輯,圖論,組合,代數,數論。這個當然不現實,因為沒那麼多課時。也許將來可以開三門課:集合與邏輯,圖論與組合,代數與數論。(這方面我們學校已經著手開始做了)不管課怎麼開,學生總一樣要學。下面分別談談上面的三組內容。
古典集合論,北師大出過一本《基礎集合論》不錯。
數理邏輯,中科院軟體所陸鍾萬教授的《面向計算機科學的數理邏輯》就不錯。現在可以找到陸鍾萬教授的講課錄像,自己去看看吧。總的來說,學集合/邏輯起手不難,普通高中生都能看懂。但越往後越感覺深不可測。
學完以上各書之後,如果你還有精力興趣進一步深究,那麼可以試一下GTM系列中的《Introction to Axiomatic Set Theory》和《A Course of Mathematical Logic》。這兩本都有世界圖書出版社的引進版。你如果能搞定這兩本,可以說在邏輯方面真正入了門,也就不用再浪費時間聽我瞎侃了。
據說全中國最多隻有三十個人懂圖論。此言不虛。圖論這東東,技巧性太強,幾乎每個問題都有一個獨特的方法,讓人頭痛。不過這也正是它魅力所在:只要你有創造性,它就能給你成就感。我的導師說,圖論裡面隨便揪一塊東西就可以寫篇論文。大家可以體會裡面內容之深廣了吧!國內的圖論書中,王樹禾老師的「圖論及其演算法」非常成功。一方面,其內容在國內教材里算非常全面的。另一方面,其對演算法的強調非常適合計算機系(本來就是科大計算機系教材)。有了這本書為主,再參考幾本翻譯的,如Bondy & Murty的《圖論及其應用》,人民郵電出版社翻譯的《圖論和電路網路》等等,就馬馬虎虎,對本科生足夠了。再進一步,世界圖書引進有GTM系列的"Modern Graph Theory"。此書確實經典!國內好象還有一家出版了個翻譯版。不過,學到這個層次,還是讀原版好。搞定這本書,也標志著圖論入了門。 外版的書好就好在這里,最新的科技成果裡面都有論述,別的先不說,至少是「緊跟時代的理論知識」。
組合感覺沒有太適合的國產書。還是讀Graham和Knuth等人合著的經典「具體數學」吧,西安電子科技大學出版社有翻譯版。
抽象代數,國內經典為莫宗堅先生的「代數學」。此書是北大數學系教材,深得好評。然而對本科生來說,此書未免太深。可以先學習一些其它的教材,然後再回頭來看「代數學」。國際上的經典可就多了,GTM系列裡就有一大堆。推薦一本談不上經典,但卻最簡單的,最容易學的:這本「Introction to Linear and Abstract Algebra"非常通俗易懂,而且把抽象代數和線性代數結合起來,對初學者來說非常理想,我校比較牛的同學都有收藏。
數論方面,國內有經典而且以困難著稱的」初等數論「(潘氏兄弟著,北大版)。再追溯一點,還有更加經典(可以算世界級)並且更加困難的」數論導引「(華羅庚先生的名著,科學版,九章書店重印,繁體的看起來可能比較困難)。把基礎的幾章搞定一個大概,對本科生來講足夠了。但這只是初等數論。本科畢業後要學計算數論,你必須看英文的書,如Bach的"Introction to Algorithmic Number Theory"。
計算機科學理論的根本,在於演算法。現在很多系裡給本科生開設演算法設計與分析,確實非常正確。環顧西方世界,大約沒有一個三流以上計算機系不把演算法作為必修的。演算法教材目前公認以Corman等著的"Introction to Algorithms"為最優。對入門而言,這一本已經足夠,不需要再參考其它書。
再說說形式語言與自動機。我看過北郵的教材,應該說寫的還清楚。但是,有一點要強調:形式語言和自動機的作用主要在作為計算模型,而不是用來做編譯。事實上,編譯前端已經是死領域,沒有任何open problems,北科大的班曉娟博士也曾經說過,編譯的技術已相當成熟。如果為了這個,我們完全沒必要去學形式語言--用用yacc什麼的就完了。北郵的那本在國內還算比較好,但是在深度上,在跟可計算性的聯繫上都有較大的局限,現代感也不足。所以建議有興趣的同學去讀英文書,不過國內似乎沒引進這方面的教材。可以去互動出版網上看一看。入門以後,把形式語言與自動機中定義的模型,和數理邏輯中用遞歸函數定義的模型比較一番,可以說非常有趣。現在才知道,什麼叫「宮室之美,百官之富」!
計算機科學和數學的關系有點奇怪。二三十年以前,計算機科學基本上還是數學的一個分支。而現在,計算機科學擁有廣泛的研究領域和眾多的研究人員,在很多方面反過來推動數學發展,從某種意義上可以說是孩子長得比媽媽還高了。但不管怎麼樣,這個孩子身上始終流著母親的血液。這血液是the mathematical underpinning of computer science(計算機科學的數學基礎),也就是理論計算機科學。原來在東方大學城圖書館中曾經看過一本七十年代的譯本(書皮都沒了,可我就愛關注這種書),大概就叫《計算機數學》。那本書若是放在當時來講決是一本好書,但現在看來,涵蓋的范圍還算廣,深度則差了許多,不過推薦大一的學生倒可以看一看,至少可以使你的計算數學入入門。
最常和理論計算機科學放在一起的一個詞是什麼?答:離散數學。這兩者的關系是如此密切,以至於它們在不少場合下成為同義詞。(這一點在前面的那本書中也有體現)傳統上,數學是以分析為中心的。數學系的同學要學習三四個學期的數學分析,然後是復變函數,實變函數,泛函數等等。實變和泛函被很多人認為是現代數學的入門。在物理,化學,工程上應用的,也以分析為主。
隨著計算機科學的出現,一些以前不太受到重視的數學分支突然重要起來。人們發現,這些分支處理的數學對象與傳統的分析有明顯的區別:分析研究的問題解決方案是連續的,因而微分,積分成為基本的運算;而這些分支研究的對象是離散的,因而很少有機會進行此類的計算。人們從而稱這些分支為「離散數學」。「離散數學」的名字越來越響亮,最後導致以分析為中心的傳統數學分支被相對稱為「連續數學」。
離散數學經過幾十年發展,基本上穩定下來。一般認為,離散數學包含以下學科 :
1) 集合論,數理邏輯與元數學。這是整個數學的基礎,也是計算機科學的基礎。
2) 圖論,演算法圖論;組合數學,組合演算法。計算機科學,尤其是理論計算機科學的核心是
演算法,而大量的演算法建立在圖和組合的基礎上。
3) 抽象代數。代數是無所不在的,本來在數學中就非常重要。在計算機科學中,人們驚訝地發現代數竟然有如此之多的應用。
但是,理論計算機科學僅僅就是在數學的上面加上「離散」的帽子這么簡單嗎?一直到大約十幾年前,終於有一位大師告訴我們:不是。D.E.Knuth(他有多偉大,我想不用我廢話了)在Stanford開設了一門全新的課程Concrete Mathematics。 Concrete這個詞在這里有兩層含義:
首先:對abstract而言。Knuth認為,傳統數學研究的對象過於抽象,導致對具體的問題關心不夠。他抱怨說,在研究中他需要的數學往往並不存在,所以他只能自己去創造一些數學。為了直接面向應用的需要,他要提倡「具體」的數學。在這里我做一點簡單的解釋。例如在集合論中,數學家關心的都是最根本的問題--公理系統的各種性質之類。而一些具體集合的性質,各種常見集合,關系,映射都是什麼樣的,數學家覺得並不重要。然而,在計算機科學中應用的,恰恰就是這些具體的東西。Knuth能夠首先看到這一點,不愧為當世計算機第一人。其次,Concrete是Continuous(連續)加上discrete(離散)。不管連續數學還是離散數學,都是有用的數學!
理論與實際的結合--計算機科學研究的范疇
前面主要是從數學角度來看的。從計算機角度來看,理論計算機科學目前主要的研究領域包括:可計算性理論,演算法設計與復雜性分析,密碼學與信息安全,分布式計算理論,並行計算理論,網路理論,生物信息計算,計算幾何學,程序語言理論等等。這些領域互相交叉,而且新的課題在不斷提出,所以很難理出一個頭緒來。想搞搞這方面的工作,推薦看中國計算機學會的一系列書籍,至少代表了我國的權威。下面隨便舉一些例子。
由於應用需求的推動,密碼學現在成為研究的熱點。密碼學建立在數論(尤其是計算數論),代數,資訊理論,概率論和隨機過程的基礎上,有時也用到圖論和組合學等。很多人以為密碼學就是加密解密,而加密就是用一個函數把數據打亂。這樣的理解太淺顯了。
現代密碼學至少包含以下層次的內容:
第一,密碼學的基礎。例如,分解一個大數真的很困難嗎?能否有一般的工具證明協議正確?
第二,密碼學的基本課題。例如,比以前更好的單向函數,簽名協議等。
第三,密碼學的高級問題。例如,零知識證明的長度,秘密分享的方法。
第四,密碼學的新應用。例如,數字現金,叛徒追蹤等。
在分布式系統中,也有很多重要的理論問題。例如,進程之間的同步,互斥協議。一個經典的結果是:在通信信道不可靠時,沒有確定型演算法能實現進程間協同。所以,改進TCP三次握手幾乎沒有意義。例如時序問題。常用的一種序是因果序,但因果序直到不久前才有一個理論上的結果....例如,死鎖沒有實用的方法能完美地對付。例如,......操作系統研究過就自己去舉吧!
如果計算機只有理論,那麼它不過是數學的一個分支,而不成為一門獨立的科學。事實上,在理論之外,計算機科學還有更廣闊的天空。
我一直認為,4年根本不夠學習計算機的基礎知識,因為面太寬了,8年,應該差不多了......
這方面我想先說說我們系在各校普遍開設的《計算機基礎》。在高等學校開設《計算機基礎課程》是我國高教司明文規定的各專業必修課程要求。主要內容是使學生初步掌握計算機的發展歷史,學會簡單的使用操作系統,文字處理,表格處理功能和初步的網路應用功能。但是在計算機科學系教授此門課程的目標決不能與此一致。在計算機系課程中目標應是:讓學生較為全面的了解計算機學科的發展,清晰的把握計算機學科研究的方向,發展的前沿即每一個課程在整個學科體系中所處的地位。搞清各學科的學習目的,學習內容,應用領域。使學生在學科學習初期就對整個學科有一個整體的認識,以做到在今後的學習中清楚要學什麼,怎麼學。計算機基本應用技能的位置應當放在第二位或更靠後,因為這一點對於本系的學生應當有這個摸索能力。這一點很重要。推薦給大家一本書:機械工業出版社的《計算機文化》(New Perspective of Computer Science),看了這本書我才深刻的體會到自己還是個計算機科學初學者,才比較透徹的了解了什麼是計算機科學。
一個一流計算機系的優秀學生決不該僅僅是一個編程高手,但他一定首先是一個編程高手。我上大學的時候,第一門專業課是C語言程序設計,念計算機的人從某種角度講相當一部分人是靠寫程序吃飯的。關於第一程序設計語言該用哪一種。我個人認為,用哪種語言屬於末節,關鍵在養成良好的編程習慣。當年老師對我們說,打好基礎後學一門新語言只要一個星期。現在我覺得根本不用一個星期,前提是先把基礎打好。不要再猶豫了,學了再說,等你抉擇好了,別人已經會了幾門語言了。
匯編語言和微機原理是兩門特煩人的課。你的數學/理論基礎再好,也占不到什麼便宜。這兩門課之間的次序也好比先有雞還是先有蛋,無論你先學哪門,都會牽扯另一門課里的東西。所以,只能靜下來慢慢琢磨。這就是典型的工程課,不需要太多的聰明和頓悟,卻需要水滴石穿的漸悟。有關這兩門課的書,計算機書店裡不難找到。弄幾本最新的,對照著看吧。組成原理推薦《計算機組成與結構》清華大學王愛英教授寫的。匯編語言大家拿8086/8088入個門,之後一定要學80x86匯編語言。實用價值大,不落後,結構又好,寫寫高效病毒,高級語言里嵌一點匯編,進行底層開發,總也離不開他,推薦清華大學沈美明的《IBM-PC匯編語言程序設計》。有些人說不想了解計算機體系結構,也不想製造計算機,所以諸如計算機原理,匯編語言,介面之類的課覺得沒必要學,這樣合理嗎?顯然不合理,這些東西遲早得掌握,肯定得接觸,而且,這是計算機專業與其他專業學生相比的少有的幾項優勢。做項目的時候,了解這些是非常重要的,不可能說,僅僅為了技術而技術,只懂技術的人最多做一個編碼工人,而永遠不可能全面地了解整個系統的設計,而編碼工人是越老越不值錢。關於組成原理還有個講授的問題,在我學這門課程時老師講授時把CPU工作原理譽微程序設計這一塊略掉了,理由是我們國家搞CPU技術不如別的國家,搞了這么長時間好不容易出了個龍芯比Intel的還差個十萬八千里,所以建議我們不要學了。我看這在各校也未見得不是個問題吧!若真是如他所說,那中國的計算機科學哪個方向都可以停了,軟硬體,應用,有幾項搞得過美國,搞不過別人就不搞了,那我們坐在這里干什麼?教學的觀念需要轉變的。
模擬電路這東東,如今不僅計算機系學生搞不定,電子系學生也多半害怕。如果你真想軟硬體通吃,那麼建議你先看看邱關源的「電路原理」,也許此後再看模擬電路底氣會足些。教材:康華光的「電子技術基礎」(高等教育出版社)還是不錯的(我校電子系在用)。有興趣也可以參考童詩白的書。
數字電路比模擬電路要好懂得多。清華大學閻石的書算一本好教材,遺憾的一點是集成電路講少了些。真有興趣,看一看大規模數字系統設計吧(北航那本用的還比較多)。
計算機系統結構該怎麼教,國際上還在爭論。國內能找到的較好教材為Stallings的"Computer Organization and Architecture:Designing for Performance"(清華影印
本)。國際上最流行的則是「Computer architecture: aquantitative approach", by Patterson & Hennessy。
操作系統可以隨便選用《操作系統的內核設計與實現》和《現代操作系統》兩書之一。這兩部都可以算經典,唯一缺點就是理論上不夠嚴格。不過這領域屬於Hardcore System,所以在理論上馬虎一點也情有可原。想看理論方面的就推薦清華大學出版社《操作系統》吧,高教司司長張堯學寫的,我們教材用的是那本。 另外推薦一本《Windows操作系統原理》機械工業出版社的,這本書是我國操作系統專家在微軟零距離考察半年,寫作歷時一年多寫成的,教操作系統的專家除了清華大學的張堯學(現高教司司長)幾乎所有人都參加了。Bill Gates親自寫序。裡面不但結合windows2000,xp詳述操作系統的內核,而且後面講了一些windows編程基礎,有外版書的味道,而且上面一些內容可以說在國內外只有那本書才有對windows內核細致入微的介紹,
如果先把形式語言學好了,則編譯原理中的前端我看只要學四個演算法:最容易實現的遞歸下降;最好的自頂向下演算法LL(k);最好的自底向上演算法LR(k);LR(1)的簡化SLR(也許還有另一簡化LALR)。後端完全屬於工程性質,自然又是another story。
推薦教材:Kenneth C.Louden寫的「Compiler Construction Principles and Practice」即是《編譯原理及實踐》(機械工業出版社的譯本)
學資料庫要提醒大家的是,會用VFP,VB, Power builder不等於懂資料庫。(這世界上自以為懂資料庫的人太多了!)資料庫設計既是科學又是藝術,資料庫實現則是典型的工程。所以從某種意義上講,資料庫是最典型的一門計算機課程--理工結合,互相滲透。另外推薦大家學完軟體工程學後再翻過來看看資料庫技術,又會是一番新感覺。推薦教材:Abraham Silberschatz等著的 "Database System Concepts".作為知識的完整性,還推薦大家看一看機械工業出版社的《數據倉庫》譯本。
計算機網路的標准教材還是來自Tanenbaum的《Computer Networks》(清華大學有譯本)。還有就是推薦謝希仁的《計算機網路教程》(人民郵電出版社)問題講得比較清楚,參考文獻也比較權威。不過,網路也屬於Hardcore System,所以光看書是不夠的。建議多讀RFC,里可以按編號下載RFC文檔。從IP的讀起。等到能掌握10種左右常用協議,就沒有幾個人敢小看你了。再做的工作我看放在網路設計上就比較好了。
數據結構的重要性就不言而喻了,學完數據結構你會對你的編程思想進行一番革命性的洗禮,會對如何建立一個合理高效的演算法有一個清楚的認識。對於演算法的建立我想大家應當注意以下幾點:
當遇到一個演算法問題時,首先要知道自己以前有沒有處理過這種問題.如果見過,那麼你一般會順利地做出來;如果沒見過,那麼考慮以下問題:
1. 問題是否是建立在某種已知的熟悉的數據結構(例如,二叉樹)上?如果不是,則要自己設計數據結構。
2. 問題所要求編寫的演算法屬於以下哪種類型?(建立數據結構,修改數據結構,遍歷,查找,排序...)
3. 分析問題所要求編寫的演算法的數學性質.是否具備遞歸特徵?(對於遞歸程序設計,只要設計出合理的參數表以及遞歸結束的條件,則基本上大功告成.)
4. 繼續分析問題的數學本質.根據你以前的編程經驗,設想一種可能是可行的解決辦法,並證明這種解決辦法的正確性.如果題目對演算法有時空方面的要求,證明你的設想滿足其要求.一般的,時間效率和空間效率難以兼得.有時必須通過建立輔助存儲的方法來節省時間.
5. 通過一段時間的分析,你對解決這個問題已經有了自己的一些思路.或者說,你已經可以用自然語言把你的演算法簡單描述出來.繼續驗證其正確性,努力發現其中的錯誤並找出解決辦法.在必要的時候(發現了無法解決的矛盾),推翻自己的思路,從頭開始構思.
6. 確認你的思路可行以後,開始編寫程序.在編寫代碼的過程中,盡可能把各種問題考慮得詳細,周密.程序應該具有良好的結構,並且在關鍵的地方配有注釋.
7. 舉一個例子,然後在紙上用筆執行你的程序,進一步驗證其正確性.當遇到與你的設想不符的情況時,分析問題產生的原因是編程方面的問題還是演算法思想本身有問題.
8. 如果程序通過了上述正確性驗證,那麼在將其進一步優化或簡化。
9. 撰寫思路分析,注釋.
對於具體的演算法思路,只能靠你自己通過自己的知識和經驗來加以獲得,沒有什麼特定的規律(否則程序員全部可以下崗了,用機器自動生成代碼就可以了).要有豐富的想像力,就是說當一條路走不通時,不要鑽牛角尖,要敢於推翻自己的想法.我也只不過是初學者,說出上面的一些經驗,僅供大家參考和討論。
關於人工智慧,我覺得的也是非常值得大家仔細研究的,雖然不能算是剛剛興起的學科了,但是絕對是非常有發展前途的一門學科。我國人工智慧創始人之一,北京科技大學塗序彥教授(這老先生是我的導師李小堅博士的導師)對人工智慧這樣定義:人工智慧是模?
⑧ 編譯原理 題目
習題一、單項選擇題
1、將編譯程序分成若干個「遍」是為了 。
a.提高程序的執行效率
b.使程序的結構更加清晰
c.利用有限的機器內存並提高機器的執行效率
d.利用有限的機器內存但降低了機器的執行效率
2、構造編譯程序應掌握 。
a.源程序 b.目標語言
c.編譯方法 d.以上三項都是
3、變數應當 。
a.持有左值 b.持有右值
c.既持有左值又持有右值 d.既不持有左值也不持有右值
4、編譯程序絕大多數時間花在 上。
a.出錯處理 b.詞法分析
c.目標代碼生成 d.管理表格
5、 不可能是目標代碼。
a.匯編指令代碼 b.可重定位指令代碼
c.絕對指令代碼 d.中間代碼
6、使用 可以定義一個程序的意義。
a.語義規則 b.詞法規則
c.產生規則 d.詞法規則
7、詞法分析器的輸入是 。
a.單詞符號串 b.源程序
c.語法單位 d.目標程序
8、中間代碼生成時所遵循的是- 。
a.語法規則 b.詞法規則
c.語義規則 d.等價變換規則
9、編譯程序是對 。
a.匯編程序的翻譯 b.高級語言程序的解釋執行
c.機器語言的執行 d.高級語言的翻譯
10、語法分析應遵循 。
a.語義規則 b.語法規則
c.構詞規則 d.等價變換規則
解答
1、將編譯程序分成若干個「遍」是為了使編譯程序的結構更加清晰,故選b。
2、構造編譯程序應掌握源程序、目標語言及編譯方法等三方面的知識,故選d。
3、對編譯而言,變數既持有左值又持有右值,故選c。
4、編譯程序打交道最多的就是各種表格,因此選d。
5、目標代碼包括匯編指令代碼、可重定位指令代碼和絕對指令代碼3種,因此不是目標代碼的只能選d。
6、詞法分析遵循的是構詞規則,語法分析遵循的是語法規則,中間代碼生成遵循的是語義規則,並且語義規則可以定義一個程序的意義。因此選a。
7、b 8、c 9、d 10、c
二、多項選擇題
1、編譯程序各階段的工作都涉及到 。
a.語法分析 b.表格管理 c.出錯處理
d.語義分析 e.詞法分析
2、編譯程序工作時,通常有 階段。
a.詞法分析 b.語法分析 c.中間代碼生成
d.語義檢查 e.目標代碼生成
解答
1.b、c 2. a、b、c、e
三、填空題
1、解釋程序和編譯程序的區別在於 。
2、編譯過程通常可分為5個階段,分別是 、語法分析 、代碼優化和目標代碼生成。 3、編譯程序工作過程中,第一段輸入是 ,最後階段的輸出為 程序。
4、編譯程序是指將 程序翻譯成 程序的程序。 解答
是否生成目標程序 2、詞法分析 中間代碼生成 3、源程序 目標代碼生成 4、源程序 目標語言
一、單項選擇題
1、文法G:S→xSx|y所識別的語言是 。
a. xyx b. (xyx)* c. xnyxn(n≥0) d. x*yx*
2、文法G描述的語言L(G)是指 。
a. L(G)={α|S+ ⇒α , α∈VT*} b. L(G)={α|S*⇒α, α∈VT*}
c. L(G)={α|S*⇒α,α∈(VT∪VN*)} d. L(G)={α|S+ ⇒α, α∈(VT∪VN*)}
3、有限狀態自動機能識別 。
a. 上下文無關文法 b. 上下文有關文法
c.正規文法 d. 短語文法
4、設G為算符優先文法,G的任意終結符對a、b有以下關系成立 。
a. 若f(a)>g(b),則a>b b.若f(a)<g(b),則a<b
c. a~b都不一定成立 d. a~b一定成立
5、如果文法G是無二義的,則它的任何句子α 。
a. 最左推導和最右推導對應的語法樹必定相同
b. 最左推導和最右推導對應的語法樹可能不同
c. 最左推導和最右推導必定相同
d. 可能存在兩個不同的最左推導,但它們對應的語法樹相同
6、由文法的開始符經0步或多步推導產生的文法符號序列是 。
a. 短語 b.句柄 c. 句型 d. 句子
7、文法G:E→E+T|T
T→T*P|P
P→(E)|I
則句型P+T+i的句柄和最左素短語為 。
a.P+T和i b. P和P+T c. i和P+T+i d.P和T
8、設文法為:S→SA|A
A→a|b
則對句子aba,下面 是規范推導。
a. SÞSAÞSAAÞAAAÞaAAÞabAÞaba
b. SÞSAÞSAAÞAAAÞAAaÞAbaÞaba
c. SÞSAÞSAAÞSAaÞSbaÞAbaÞaba
d. SÞSAÞSaÞSAaÞSbaÞAbaÞaba
9、文法G:S→b|∧(T)
T→T,S|S
則FIRSTVT(T) 。
a. {b,∧,(} b. {b,∧,)} c.{b,∧,(,,} d.{b,∧,),,}
10、產生正規語言的文法為 。
a. 0型 b. 1型 c. 2型 d. 3型
11、採用自上而下分析,必須 。
a. 消除左遞歸 b. 消除右遞歸 c. 消除回溯 d. 提取公共左因子
12、在規范歸約中,用 來刻畫可歸約串。
a. 直接短語 b. 句柄 c. 最左素短語 d. 素短語
13、有文法G:E→E*T|T
T→T+i|i
句子1+2*8+6按該文法G歸約,其值為 。
a. 23 B. 42 c. 30 d. 17
14、規范歸約指 。
a. 最左推導的逆過程 b. 最右推導的逆過程
c. 規范推導 d. 最左歸約的逆過程
[解答]
1、選c。
2、選a。
3、選c。
4、雖然a與b沒有優先關系,但構造優先函數後,a與b就一定存在優先關系了。所以,由f(a)>g)(b)或f(a)<g(b)並不能判定原來的a與b之間是否存在優先關系:故選c。
5、如果文法G無二義性,則最左推導是先生長右邊的枝葉:對於d,如果有兩個不同的是了左推導,則必然有二義性。故選a。
6、選c。
7、由圖2-8-1的語法樹和優先關系可以看出應選b。
8、規范推導是最左推導,故選d。
9、由T→T,…和T→(… 得FIRSTVT(T))={(,,)};
由T→S得FIRSTVT(S)⊂FIRSTVT(T),而FIRSTVT(S)={b,∧,(};即
FIRSTVT(T)={b,∧,(,,}; 因此選c。
10、d 11、c 12、b 13、b 14、b
二、多項選擇題
1、下面哪些說法是錯誤的 。
a. 有向圖是一個狀態轉換圖 b. 狀態轉換圖是一個有向圖
c.有向圖是一個DFA d.DFA可以用狀態轉換圖表示
2、對無二義性文法來說,一棵語法樹往往代表了 。
a. 多種推導過程 b. 多種最左推導過程 c.一種最左推導過程
d.僅一種推導過程 e.一種最左推導過程
3、如果文法G存在一個句子,滿足下列條件 之一時,則稱該文法是二義文法。
a. 該句子的最左推導與最右推導相同
b. 該句子有兩個不同的最左推導
c. 該句子有兩棵不同的最右推導
d. 該句子有兩棵不同的語法樹
e.該句子的語法樹只有一個
4、有一文法G:S→AB
A→aAb|ε
B→cBd|ε
它不產生下面 集合。
a. {anbmcndm|n,m≥0} b. {anbncmdm|n,m>0}
c. {anbmcmdn|n,m≥0} d. {anbncmdm|n,m≥0}
e. {anbncndn|n≥0}
5、自下而上的語法分析中,應從 開始分析。
a. 句型 b. 句子 c. 以單詞為單位的程序
d. 文法的開始符 e. 句柄
6、對正規文法描述的語言,以下 有能力描述它。
a.0型文法 b.1型文法 c.上下文無關文法 d.右線性文法 e.左線性文法
解答 1、e、a、c 2、a、c、e 3、b、c、d 4、a、c 5、b、c 6、a、b、c、d、e
三、填空題
1、文法中的終結符和非終結符的交集是 。詞法分析器交給語法分析器的文法符號一定是 ,它一定只出現在產生式的 部。
2、最左推導是指每次都對句型中的 非終結符進行擴展。
3、在語法分析中,最常見的兩種方法一定是 分析法,另一是 分析法。
4、採用 語法分析時,必須消除文法的左遞歸。
5、 樹代表推導過程, 樹代表歸約過程。
6、自下而上分析法採用 、歸約、錯誤處理、 等四種操作。
7、Chomsky把文法分為 種類型,編譯器構造中採用 和 文法,它們分別產生 和 語言,並分別用 和 自動機識別所產生的語言。
解答 1、空集 終結符 右
2、最左
3、自上而上 自下而上
4、自上而上
5、語法 分析
6、移進 接受
7、4 2 型 3型 上下文無關語言 正規語言 下推自動機 有限
四、判斷題
1、文法 S→aS|bR|ε描述的語言是(a|bc)* ( )
R→cS
2、在自下而上的語法分析中,語法樹與分析樹一定相同。 ( )
3、二義文法不是上下文無關文法。 ( )
4、語法分析時必須先消除文法中的左遞歸。 ( )
5、規范歸約和規范推導是互逆的兩個過程。 ( )
6、一個文法所有句型的集合形成該文法所能接受的語言。 ( )
解答 1、對 2、錯 3、錯 4、錯 5、錯 6、錯
五、簡答題
1、句柄 2、素短語 3、語法樹 4、歸約 5、推導
[解答]
1、句柄:一個句型的最左直接短語稱為該句型的句柄。
2、素短語:至少含有一個終結符的素短語,並且除它自身之外不再含任何更小的素短語。
3、語法樹:滿足下面4個條件的樹稱之為文法G[S]的一棵語法樹。
①每一終結均有一標記,此標記為VN∪VT中的一個符號;
②樹的根結點以文法G[S]的開始符S標記;
③若一結點至少有一個直接後繼,則此結點上的標記為VN中的一個符號;
④若一個以A為標記的結點有K個直接後繼,且按從左至右的順序,這些結點的標記分別為X1,X2,…,XK,則A→X1,X2,…,XK,必然是G的一個產生式。
4、歸約:我們稱αγβ直接歸約出αAβ,僅當A→γ 是一個產生式,且α、β∈(VN∪VT)*。歸約過程就是從輸入串開始,反復用產生式右部的符號替換成產生式左部符號,直至文法開始符。
5、推導:我們稱αAβ直接推出αγβ,即αAβÞαγβ,僅當A→ γ 是一個產生式,且α、β∈(VN∪VT)*。如果α1Þα2Þ…Þαn,則我們稱這個序列是從α1至α2的一個推導。若存在一個從α1αn的推導,則稱α1可推導出αn。推導是歸約的逆過程。
六、問答題
1、給出上下文無關文法的定義。
[解答]
一個上下文無關文法G是一個四元式(VT,VN,S, P),其中:
●VT是一個非空有限集,它的每個元素稱為終結符號;
●VN是一個非空有限集,它的每個元素稱為非終結符號,VT∩VN=Φ;
●S是一個非終結符號,稱為開始符號;
●P是一個產生式集合(有限),每個產生式的形式是P→α,其中,P∈VN,
α∈(VT∪VN)*。開始符號S至少必須在某個產生式的左部出現一次。
2、文法G[S]:
S→aSPQ|abQ
QP→PQ
bP→bb
bQ→bc
cQ→cc
(1)它是Chomsky哪一型文法?
(2)它生成的語言是什麼?
[解答]
(1)由於產生式左部存在終結符號,且所有產生式左部符號的長度均小於等於產生式右部的符號長度,所以文法G[S]是Chomsky1型文法,即上下文有關文法。
(2)按產生式出現的順序規定優先順序由高到低(否則無法推出句子),我們可以得到:
SÞabQÞabc
SÞaSPQÞaabQPQÞaabPQQÞaabbQQÞaabbcQÞaabbcc
SÞaSPQÞaaSPQPQÞaaabQPQPQÞaaabPQQPQÞaaabPQPQQÞaaaPPQQQÞ
aaabbPqqqÞaaabbQQQÞaaabbbcQQÞaaabbbccQÞaaabbbccc
……
於是得到文法G[S]生成的語言L={anbncn|n≥1}
3、按指定類型,給出語言的文法。
L={aibj|j>i≥1}的上下文無關文法。
【解答】
(1)由L={aibj|j>i≥1}知,所求該語言對應的上下文無關文法首先應有S→aSb型產生式,以保證b的個數不少於a的個數;其次,還需有S→Sb或S→bS型的產生式,用以保證b的個數多於a的個數;也即所求上下文無關文法G[S]為:
G[S]:S→aSb|Sb|b
4、有文法G:S→aAcB|Bd
A→AaB|c
B→bScA|b
(1)試求句型aAaBcbbdcc和aAcbBdcc的句柄;
(2)寫出句子acabcbbdcc的最左推導過程。
【解答】(1)分別畫出對應兩句型的語法樹,如圖2-8-2所示
句柄:AaB Bd
圖2-8-2 語法樹
(2)句子acabcbbdcc的最左推導如下:
SÞaAcBÞaAaBcBÞacaBcBÞacabcBÞacabcbScAÞacabcbBdcA
ÞacabcbbdcAÞacabcbbdcc
5、對於文法G[S]:
S→(L)|aS|a L→L, S|S
(1)畫出句型(S,(a))的語法樹。(2)寫出上述句型的所有短語、直接短語、句柄和素短語。
【解答】
(1)句型(S,(a))的語法樹如圖2-8-3所示
(2)由圖2-8-3可知:
①短語:S、a、(a)、S,(a)、(S,(a));
②直接短語:a、S;
③句柄:S;
④素短語:素短語可由圖2-8-3中相鄰終結符之間的優先關系求得,即;
因此素短語為a。
6、考慮文法G[T]:
T→T*F|F
F→F↑P|P
P→(T)|i
證明T*P↑(T*F)是該文法的一個句型,並指出直接短語和句柄。
【解答】
首先構造T*P↑(T*F)的語法樹如圖2-8-4所示。
由圖2-8-4可知,T*P↑(T*F)是文法G[T]的一個句型。
直接短語有兩個,即P和T*F;句柄為P。
一、單項選擇題
1、詞法分析所依據的是 。
a. 語義規則 b. 構詞規則 c. 語法規則 d. 等價變換規則
2、詞法分析器的輸出結果是 。
a. 單詞的種別編碼 b. 單詞在符號表中的位置
c. 單詞的種別編碼和自身值 d. 單詞自身值
3、正規式M1和M2等價是指 。
a. M1和M2的狀態數相等 b. M1和M2的有向弧條數相等
c. M1和M2所識別的語言集相等 d. M1和M2狀態數和有向弧條數相等
4、狀態轉換圖(見圖3-6-1)接受的字集為 。
a. 以 0開頭的二進制數組成的集合 b. 以0結尾的二進制數組成的集合
c. 含奇數個0的二進制數組成的集合 d. 含偶數個0的二進制數組成的集合
5、詞法分析器作為獨立的階段使整個編譯程序結構更加簡潔、明確,因此, 。
a. 詞法分析器應作為獨立的一遍 b. 詞法分析器作為子程序較好
c. 詞法分析器分解為多個過程,由語法分析器選擇使用 d. 詞法分析器並不作為一個獨立的階段
解答 1、b 2、c 3、c 4、d 5、b
二、多項選擇題
1、在詞法分析中,能識別出 。
a. 基本字 b. 四元式 c. 運算符
d. 逆波蘭式 e. 常數
2、令∑={a,b},則∑上所有以b開頭,後跟若干個ab的字的全體對應的正規式為 。
a. b(ab)* b. b(ab)+ c.(ba)*b
d. (ba)+b e. b(a|b)
解答 1、a、c、e 2、a、b、d
三、填空題
1、確定有限自動機DFA是 的一個特例。
2、若二個正規式所表示的 相同,則認為二者是等價的。
3、一個字集是正規的,當且僅當它可由 所 。
解答 1、NFA 2、正規集 3、DFA(NFA)所識別
四、判斷題
1、一個有限狀態自動機中,有且僅有一個唯一終態。 ( )
2、設r和s分別是正規式,則有L(r|s)=L(r)|L(s)。 ( )
3、自動機M和M′的狀態數不同,則二者必不等價。 ( )
4、確定的自動機以及不確定的自動機都能正確地識別正規集。 ( )
5、對任意一個右線性文法G,都存在一個NFA M,滿足L(G)=L(M)。 ( )
6、對任意一個右線性文法G,都存在一個DFA M,滿足L(G)=L(M)。 ( )
7、對任何正規表達式e,都存在一個NFA M,滿足L(G)=L(e)。 ( )
8、對任何正規表達式e,都存在一個DFA M,滿足L(G)=L(e)。 ( )
解答 1 、2、3、錯 4、5、6、7、8、正確
五、基本題
1、設M=({x,y}, {a,b}, f,x,{y})為一非確定的有限自動機,其中f定義如下:
f(x,a)={x,y} f(x,b)={y}
f(y,a)=φ f(y,b)={x,y}
試構造相應的確定有限自動機M′。
解答:對照自動機的定義M=(S,Σ,f,S0,Z),由f的定義可知f(x,a)、f(y,b)均為多值函數,所以是一非確定有限自動機,先畫出NFA M相應的狀態圖,如圖3-6-2所示。
用子集法構造狀態轉換矩陣表3-6-3所示。
I Ia Ib
{x} {x,y} {y}
{y} — {x,y}
{x,y} {x,y} {x,y}
將轉換矩陣中的所有子集重新命名而形成表3-6-4所示的狀態轉換矩陣。
表3-6-4 狀態轉換矩陣
a b
0 2 1
1 — 2
2 2 2
即得到M′=({0,1,2}, {a,b}, f,0, {1,2}),其狀態轉換圖如圖3-6-5所示。
將圖3-6-5的DFA M′最小化。首先,將M′的狀態分成終態組{1,2}與非終態組{0};其次,考察{1,2}。由於{1,2}a={1,2}b={2}⊂{1,2},所以不再將其劃分了,也即整個劃分只有兩組{0},{1,2}:令狀態1代表{1,2},即把原來到達2的弧都導向1,並刪除狀態2。最後,得到如圖3-6-6所示化簡DFA M′。
2、對給定正規式b*(d|ad)(b|ab)+,構造其NFA M;
解答:首先用A+=AA*改造正規式得:b*(d|ad)(b|ab)(b|ab)*;其次,構造該正規式的NFA M,如圖3-6-7所示。
求採納為滿意回答。
希望能解決您的問題。
⑨ 編譯原理中=>*表示0步或多步推導,什麼叫0步推導難道不經過產生式嗎。。
0步推導,是指符號串本身已經就是所需要推導的結果,不推導就已經是了。
不推導,當然也就不需要應用任何一個產生式。
舉個例子:
G[S]:
S-->aSb
|
ab
待推導的句子是
w=aabb
現在有3個句型u,v,z,都可以推導出w。
它們分別是:
u=S
v=aSb
z=aabb
那麼:
從句型u推導:
u=S==>aSb==>aabb,需要2步推導
從句型v推導:
v=aSb==>aabb,需要1步推導
從句型z推導:
z=aabb,需要0步推導
⑩ 編譯原理
編譯原理):利用編譯程序從源語言編寫的源程序產生目標程序的過程; 用編譯程序產生目標程序的動作。 編譯就是把高級語言變成計算機可以識別的2進制語言,計算機只認識1和0,編譯程序把人們熟悉的語言換成2進制的。
編譯程序把一個源程序翻譯成目標程序的工作過程分為五個階段:詞法分析;語法分析;語義檢查和中間代碼生成
(10)編譯原理推導長度擴展閱讀:
編譯程序的語法分析器以單詞符號作為輸入,分析單詞符號串是否形成符合語法規則的語法單位,如表達式、賦值、循環等,最後看是否構成一個符合要求的程序,按該語言使用的語法規則分析檢查每條語句是否有正確的邏輯結構,程序是最終的一個語法單位。
編譯程序的語法規則可用上下文無關文法來刻畫。語法分析的方法分為兩種:自上而下分析法和自下而上分析法。自上而下就是從文法的開始符號出發,向下推導,推出句子。
而自下而上分析法採用的是移進歸約法,基本思想是:用一個寄存符號的先進後出棧,把輸入符號一個一個地移進棧里,當棧頂形成某個產生式的一個候選式時,即把棧頂的這一部分歸約成該產生式的左鄰符號。