編譯原理語句分析流程圖
㈠ 編譯原理的數據結構
編譯原理一直是計算機學習的必修課.
當然,由編譯器的階段使用的演算法與支持這些階段的數據結構之間的交互是非常強大的。編譯器的編寫者盡可能有效實施這些方法且不引起復雜性。理想的情況是:與程序大小成線性比例的時間內編譯器,換言之就是,在0 ( n )時間內,n是程序大小的度量(通常是字元數)。本節將講述一些主要的數據結構,它們是其操作部分階段所需要的,並用來在階段中交流信息。 臨時文件(temporary file):計算機過去一直未能在編譯器時將整個程序保留在存儲器中。這一問題已經通過使用臨時文件來保存翻譯時中間步驟的結果或通過「匆忙地」編譯(也就是只保留源程序早期部分的足夠信息用以處理翻譯)解決了。存儲器的限制現在也只是一個小問題了,現在可以將整個編譯單元放在存儲器之中,特別是在可以分別編譯的語言中時。但是偶爾還是會發現需要在某些運行步驟中生成中間文件。其中典型的是代碼生成時需要反填(backpatch)地址。例如,當翻譯如下的條件語句時 if x = 0 then ... else ... 在知道else部分代碼的位置之前必須由文本跳到else部分:
CMP X,0 JNE NEXT ;;
location of NEXT not yet known < code for then-part > NEXT : < code for else-part >
通常,必須為NEXT的值留出一個空格,一旦知道該值後就會將該空格填上,利用臨時文件可以很容易地做到這一點。
如果想利用上面的編譯原理開發一套屬於自己的編程語言,或者想在一個產品中嵌入編程語言,可以參考zengl開源網開發的zengl編程語言,該編程語言為國人使用C語言開發,裡麵包含兩個部分,一個是編譯器,一個是解釋執行中間代碼的虛擬機。編譯器包含了詞法掃描,語法分析,中間代碼輸出等,虛擬機則類似JAVA一樣解釋執行中間代碼。作者將所有的版本都公布出來,好讓讀者可以由淺入深的做研究,並且為了證明該編程語言的實用性,還結合SDL游戲開發庫開發了一款圖形界面和命令行界面的21點撲克小游戲 。
zengl編程語言目前適用平台為windows和linux (最開始在Linux下使用gcc開發,後來移植到windows平台)
㈡ 循環語句的語法分析及語義分析程序設計
目 錄
1 課程任務書····································(2)
1問題描述·······································(3)
2文法及屬性文法的描述···························(3)
2.1 while-do循環語句的文法·····················(3)
2.2while-do循環語句的結構翻譯·················(3)
3語法分析及中間代碼形式的描述···················(4)
3.1 語法分析方法·······························(4)
3.2 中間代碼形式描述···························(4)
4簡要的分析與概要設計···························(5)
4.1詞法分析··································(5)
4.2遞歸下降翻譯器的設計·······················(5)
4.3語法制導翻譯·······························(5)
5 詳細的演算法描述································(6)
5.1 文法·······································(6)
5.2 查錯·······································(6)
6 測試方法和測試結果···························(9)
6.1測試方法··································(9)
6.2測試結果··································(10)
7 設計的特點、不足、收獲與體會·················(10)
7.1 設計的特點································(10)
7.2 不足、收獲與體會··························(11)
8 參考文獻·····································(11)
課程設計任務書
題 目: 循環語句的語法分析及語義分析程序設計(遞歸下降法)
1.目的
通過設計、編制、調試一個語法及語義分析程序,加深對語法及語義分析原理的理解。
2.設計內容及要求
WHILE〈布爾表達式〉DO〈賦值語句〉
其中
(1)學號29至32的同學按順序分別選擇遞歸下降法、LL(1)、算符優先分析法(或簡單優先法)、LR法完成以上任務,中間代碼選用四元式。
(2)如1題寫出符合分析方法要求的文法,給出分析方法的思想,完成分析程序設計。
(3)編制好分析程序後,設計若干用例,上機測試並通過所設計的分析程序。
3.課程設計報告書的內容應包括:
1.設計題目、班級、學號、姓名、完成日期;
2.給出語法分析方法及中間代碼形式的描述、文法和屬性文法的設計;或者詞法分析方法
3.及符號表和TOKEN代碼的設計。
4.簡要的分析與概要設計;
5.詳細的演算法描述;
6.源程序清單;
7.給出軟體的測試方法和測試結果;
8.設計的評價、收獲與體會。
4.時間安排:
第17周,周1-周4上午,周五全天
指導教師簽名: 年 月 日
系主任(或責任教師)簽名: 年 月 日
1問題描述
設計一個WHILE〈布爾表達式〉DO〈賦值語句〉循環語句的詞法﹑語法及語義分析程序,語法分析選擇遞歸下降法,採用用語法制導翻譯輸出中間代碼四元式。
2文法及屬性文法的描述。
2.1 while-do循環語句的文法
產生式為S-> while E do A,為便於語法制導翻譯將其改寫如下:
文法G(s)如下:
S-->WEDG (意思是while E do G)
G-->c=R
R-->dTe|d
T-->+|-|*|/
E-->aFb
F--> >|==|<
2.2 whlie-do循環語句的結構翻譯:
3.語法分析方法及中間代碼形式的描述
3.1語法分析方法
遞歸下降法的實現思想是為文法的每個非終結符號設計一個相對應的遞歸子程序,識別程序由一組這樣的子程序組成。
它的優點是簡單直觀,易於構造,很多編譯系統所實現
缺點是對文法要求很高,由於遞歸調用多,影響分析器的效率
其文法可以表示為:
E→T│E+T
T→F│T*F
F→i│(E)
可以用語法圖來表示語言的文法,如圖:
E
T
F
3.2中間代碼形式描述
中間代碼採用四元式輸出,一個四元式是一個帶有四個域的記錄結構,這四個域分別稱為op﹑arg1﹑arg2及result。域op包含一個代表運算符的內部碼。語句while a<b do a=a+b的四元式輸出形式如下:
100 ( <, a , b , 102 )
101 ( j , _ , _ , 105 )
102 ( + , a , b , n )
103 ( = , n , _ , a )
104 ( j , _ , _ , 100)
105
4.簡要的分析與概要設計
4.1詞法分析
詞法分析程序的任務是:從左至右逐個字元地對源程序進行掃描,產生一個個的單詞符號,把作為字元串的源程序改造成為單詞符號的中間程序。詞法分析檢查的錯誤主要是挑出源程序中出現的非法符號。所謂非法符號是指不是程序設計語言中允許出現的符號,就像自然語句中的錯字。
4.2遞歸下降翻譯器的設計
1.:對每個非終結符A構造一個函數過程,對A的每個繼承屬性設置一個形式參數,函數的返回值為A的綜合屬性,A對應的函數過程中,為出現在A的產生式中的每一個文法符號的每一個屬性都設置一個局部變數。非終結符A對應的函數過程中,根據當前的輸入符號決定使用哪個產生式候選。
2:每個產生式對應的程序代碼中,按照從左到右的次序,對於單詞符號,非3:終結符和語義動作分別做以下工作。
(1)對於帶有綜合屬性x的終結符X,把x的值存入為X,x設置的變數中。然後產生一個匹配X的調用,並繼續讀入一個輸入符號。
(2)對於每個非終結符號B,產生一個右邊帶有函數調用的賦值語句c=B(b1,b2,…,bk)
(3)對於語義動作,把動作的代碼抄進分析器中,用代表屬性的變數來代替對應屬性的每一次引用。
4.3語法制導翻譯
在語法分析過程中,隨著分析的步步進展,根據每個產生式所對應的語義子程序(或語義規則描述的語義動作)進行翻譯。屬性文法的每個符號有屬性,所以每個符號入棧時,必須連屬性一起入棧,這樣,棧符號就由文法符號及存放該符號屬性的域所組成。由於屬性類型不同,屬性域存放的內容就要根據屬性的類型來定。有的可能直接存放屬性值,也有的存放的是指向屬性值的指針。對於綜合屬性,其屬性域不存放其屬性值,而是存放一個指針,指向存貯該屬性值的單元。對於繼承屬性,其屬性域直接保存其屬性值。繼承屬性的屬性域剛入棧時為空,但是在該棧符號變成棧頂符號之前的某一時刻,它們必須接受相應的屬性值,即在成為棧頂時,繼承屬性的屬性域必須有值。
5詳細的演算法描述
5.1 文法
/*
文法G(s)
s-->WEDG
G-->c=R
R-->dTe|d
T -> +|-|*|/|%E-->aFb
F--> >|==|<
*/
5.2 查錯
按照遞歸下降法求Wa<bDa=a+b,程序的執行順序應該是S()W()EF()D()G()R()T()
S()
void S()
{
printf("%d\tS-->WEDG\n",total);total++;
W();
E();
}
W()
void W()
{
if(ch!='W')
{
printf("有非法字元%c請按回車返回!!",ch);
getchar();
getchar();
exit(1);
}
}
E()
void E()
{
ch=a[++i1];
if(ch!='a')
{
printf("有非法字元%c %c請按回車返回!!",ch);
getchar();
getchar();
exit(1);
}
printf("%d\tE-->aFb\n",total);total++;
F();
}
F()
void F()
{
int i;
ch=a[++i1];
i=i1+1;
if(a[i]!='b')
{
printf("有非法字元%c請按回車返回!!",a[i]);
getchar();
getchar();
exit(1);
}
switch(ch)
{
case '>':
printf("%d\tF-->>\n",total);total++;
break;
case '==':
printf("%d\tF-->==\n",total);total++;
break;
default:
printf("%d\tF--><\n",total);total++;
break;
}
D();
G();
}
D()
void D()
{
++i1;
ch=a[++i1];
if(ch!='D')
{
printf("有非法字元%c請按回車返回!!",ch);
getchar();
getchar();
exit(1);}
ch=a[++i1];
}
G()
void G()
{
int i=i1+1;
if(ch!='c'&&a[i]!='=')
{
printf("有非法字元%c %c請按回車返回!!",ch,a[i]);
getchar();
getchar();
exit(1);
}
printf("%d\tG-->c=R\n",total);total++;
R();
}
R()
void R()
{
int i;
i=i1+1;
i1=i1+2;
ch=a[i1];
if(a[i]!='='&&ch!='d')
{
printf("有非法字元%c %c請按回車返回!!",a[i],ch);
getchar();
getchar();
exit(1);
}
else
{
if((a[i1+1]=='+')||(a[i1+1]=='-')||(a[i1+1]=='*')||(a[i1+1]=='/'))
{
printf("%d\tR-->dTe\n",total);total++;
T();
}
else
{
printf("%d\tR-->d\n",total);total++;
W();
E();
}
}
}
T()
void T()
{
ch=a[++i1];
switch(ch)
{
case '+':
printf("%d\tT-->+\n",total);total++;
break;
case '-':
printf("%d\tT-->-\n",total);total++;
break;
case '*':
printf("%d\tT-->*\n",total);total++;
break;
default:
printf("%d\tT-->/\n",total);total++;
break;
}
ch='#';
}
6測試方法和測試結果
6.1測試方法
在C++環境下,設計幾個有代表的用例,進行測試,例如:輸入語句Wa<bDa=a+b#(其中d表示do ,w表示while)。若得出的不是預期的結果,那麼程序就出現問題。如果有問題的話就進行單步調試找到程序中出現的邏輯問題。
6.2測試結果
測試結果如下:
7設計的特點、不足、收獲與體會
7.1設計的特點
本次設計是採用遞歸下降的方法對輸入的while--do 循環語句進行語法,語義分析,並輸出四元式。因此程序中充分體現了遞歸下降的思想。
7.2設計的不足,收獲與體會
本次的設計的不足主要是我沒將程序一般化,實現不了用戶自動輸入代碼進行詞法分析的四元式輸出,此程序只能實現對Wa<bDa=a+b#的分析與四元式輸出,由於我所設計的棧中只能一個字元一個字元的存放,因此只能用D W分別表示do while;而且我對語法制導翻譯這一塊很不熟悉,因此我始終不能用程序實現語法制導翻譯輸出四元式,於是根據自己的理解,直接把四元式寫了出來。
本次課程設計鞏固了我所學習的關於遞歸下降法這一方面的知識,並且使我對WHILE—DO循環語句也有了更深刻的理解,提高了我的動手能力。
8 課程設計參考資料
1張幸兒 《編譯原理》(第二版)清華大學出版社
2何炎祥 《編譯原理》華中理工大學出版社
3陳火旺 《程序設計語言編譯原理》(第3版)國防工業出版社
本科生課程設計成績評定表
班級:軟體0701姓名:周璐萍學號:0120710680129
序號 評分項目 滿分 實得分
1 學習態度認真、遵守紀律 10
2 設計分析合理性 10
3 設計方案正確性、可行性、創造性 20
4 設計結果正確性 40
5 設計報告的規范性 10
6 設計驗收 10
總得分/等級
評語:
註:最終成績以五級分制記。優(90-100分)、良(80-89分)、中(70-79分)、
及格(60-69分)、60分以下為不及格
源程序
#include <stdio.h>
#include<dos.h>
#include<stdlib.h>
#include<string.h>
char a[50],g[50][50];
char ch;
int n1,i1=0,i2=0;
int total=0;
void S();
void D();
void G();
void W();
void E();
void R();
void T();
void F();
void main()
{
int j=0;
printf("文法G(s)為:\n");
printf("s-->DGWE\n");
printf("G-->c=R\n");
printf("R-->dTe|d\n");
printf("T-->+|-|*|/\n");
printf("E-->aFb\n");
printf("F--> >|==|<\n");
printf("請輸入while-do語句(D代表do,W代表while),並以#結束:\n");
do{
scanf("%c",&ch);
a[j]=ch;
j++;
}while(ch!='#');
n1=j;
ch=a[0];
S();
printf("\n");
if (ch=='#')
{ printf("輸出四元式為:\n");
printf("100 (<,a,b,102)\n");
printf("101 (j,_,_,105)\n");
printf("102 (+,a,b,n)\n");
printf("103 (=,n,_,a)\n");
printf("104 (j,_,_,100)\n");
printf("105 \n");
}
else {
printf("error\n");
printf("press any key to continue..\n");
getchar();getchar();
return;
}
printf("\n");
printf("press any key to continue..\n");
getchar();
getchar();
}
/*出錯情況分析*/
void S()
{
printf("%d\tS-->WEDG\n",total);total++;
W();
E();
}
void W()
{
if(ch!='W')
{
printf("有非法字元%c請按回車返回!!",ch);
getchar();
getchar();
exit(1);
}
}
void E()
{
ch=a[++i1];
if(ch!='a')
{
printf("有非法字元%c %c請按回車返回!!",ch);
getchar();
getchar();
exit(1);
}
printf("%d\tE-->aFb\n",total);total++;
F();
}
void F()
{
int i;
ch=a[++i1];
i=i1+1;
if(a[i]!='b')
{
printf("有非法字元%c請按回車返回!!",a[i]);
getchar();
getchar();
exit(1);
}
switch(ch)
{
case '>':
printf("%d\tF-->>\n",total);total++;
break;
case '==':
printf("%d\tF-->==\n",total);total++;
break;
default:
printf("%d\tF--><\n",total);total++;
break;
}
D();
G();
}
void D()
{ ++i1;
ch=a[++i1];
if(ch!='D')
{ printf("有非法字元%c請按回車返回!!",ch);
getchar();
getchar();
exit(1);}
ch=a[++i1];
}
void G()
{ int i=i1+1;
if(ch!='c'&&a[i]!='=')
{ printf("有非法字元%c %c請按回車返回!!",ch,a[i]);
getchar();
getchar();
exit(1);}
printf("%d\tG-->c=R\n",total);total++;
R();
}
void R()
{
int i;
i=i1+1;
i1=i1+2;
ch=a[i1];
if(a[i]!='='&&ch!='d')
{
printf("有非法字元%c %c請按回車返回!!",a[i],ch);
getchar();
getchar();
exit(1);
}
else
{
if((a[i1+1]=='+')||(a[i1+1]=='-')||(a[i1+1]=='*')||(a[i1+1]=='/'))
{
printf("%d\tR-->dTe\n",total);total++;
T();
}
else
{
printf("%d\tR-->d\n",total);total++;
W();
E();
}
}
}
void T()
{
ch=a[++i1];
switch(ch)
{
case '+':
printf("%d\tT-->+\n",total);total++;
break;
case '-':
printf("%d\tT-->-\n",total);total++;
break;
case '*':
printf("%d\tT-->*\n",total);total++;
break;
default:
printf("%d\tT-->/\n",total);total++;
break;
}
ch='#';
}
指導教師簽名:
2010 年月日
㈢ 編譯原理中詞法分析和語法分析的任務分別是什麼
在編譯原理中,語法規則和詞法規則不同之處在於:規則主要識別單詞,而語法主要識別多個單片語成的句子。
詞法分析和詞法分析程序:
詞法分析階段是編譯過程的第一個階段。這個階段的任務是從左到右一個字元一個字元地讀入源程序,即對構成源程序的字元流進行掃描然後根據構詞規則識別單詞(也稱單詞符號或符號)。詞法分析程序實現這個任務。詞法分析程序可以使用lex等工具自動生成。
語法分析(Syntax analysis或Parsing)和語法分析程序(Parser)
語法分析是編譯過程的一個邏輯階段。語法分析的任務是在詞法分析的基礎上將單詞序列組合成各類語法短語,如「程序」,「語句」,「表達式」等等.語法分析程序判斷源程序在結構上是否正確.源程序的結構由上下文無關文法描述.
語義分析(Syntax analysis)
語義分析是編譯過程的一個邏輯階段. 語義分析的任務是對結構上正確的源程序進行上下文有關性質的審查, 進行類型審查.語義分析將審查類型並報告錯誤:不能在表達式中使用一個數組變數,賦值語句的右端和左端的類型不匹配.
㈣ 關於編譯原理
可以自己寫一個JPanel或者JComponent的子類,然後在子類中重寫paint方法,在裡面繪制背景圖片。下面的部分是從我的代碼里截出來的,不保證這樣能用,只是給你個大體的絲路。學會了這個後自己重寫組件就方便多了 public class ChessBoard extends JComponent{ private Image screen = null; public void paint(Graphics g) { if (screen != null) { g.drawImage(screen, (width - BOARDWIDTH) / 2, (height - BOARDHEIGHT) / 2, this); } else { screen = ChessBoard.this.createImage(BOARDWIDTH,BOARDHEIGHT); } } }
㈤ 漢語程序設計語言的編譯原理
漢編系統是一個互動式的程序設計環境,最初是為程序員在小型和微型計算機上開發應用程序而設計的。主要應用於科學計算和工業控制,比如儀器、機器人、過程式控制制、圖形和圖像處理、人工智慧和商業應用。漢編語言的主要優點是軟體開發快速、互動式、計算機硬體的高效使用等。
漢編語言與傳統語言最大的不同是它的可擴展性。漢編語言的編程過程就是定義新的詞,詞實際上就是語言的新命令。詞可以用一系列以前定義的詞來定義,這個過程與教育孩子的過程相似:我們總是用孩子們以前理解的概念來教給孩子們新的概念,而這些詞被稱為「高級定義」。同樣,新的詞也可以用匯編代碼定義。
可擴展性的結果是我們在開發一個應用的同時,也間接地開發了一個特殊的、針對這一類應用的「面向應用的模塊,它可以用於或者經過修改之後被用於相似的應用。
漢編語言的可擴展性並不僅僅是為語言自身增加新的命令,所以不要把定義詞與傳統高級語言定義函數、過程等同。漢編系統還能對定義詞(建詞)進行擴展,創建一個可以定義其它詞的詞,這種詞被稱為「定義詞」。在創建這樣一個定義詞的時候,程序員能夠指定它所創建的詞在編譯時間、運行時間或者這兩種狀態下的特殊行為。這個能力允許我們定義特殊的數據類型,並對其行為和結構實施完全的控制。又由於這種詞的運行時行為可以用高級語言或者匯編語言來定義,所以由定義詞創建的詞將具有與其它漢編詞一樣的性能。系統也允許我們增加一個新的「編譯指示符」以實現特殊類型的循環或者其它的控制結構。比如,漢語言定義一個程序變數的詞:給,其代碼大概如下:
編給(32位數-<變數名>-)編譯時
(---32位數)運行時
建詞可用地址4位元組空出寫
動作讀
。
定義變數時
5給變數一
則5被自動寫入變數一的實體域中
運行「變數一」時
變數一
則變數一實體域中的數字5被自動讀取,放到數摞上 漢編詞可以使用以前定義的詞或者匯編代碼來定義,它們與其它語言的子程序相似,也與其它語言的命令等效。漢編系統允許我們在鍵盤上打入一條指令的詞名,這個詞將被立即執行。然而,如果我們把功能的詞名放到定義中,將編譯成對於這個詞的引用。
高級詞是由其它詞的集合來定義的,我們可以把這個過程想像成是其它語言的宏。新的詞被加入到它們可以使用的存儲器中,其定義被加入到詞典中。在一個漢編詞的命名規則中,只有很少的幾個字元不能作為詞名使用。
當遇到一個詞的時候,漢編系統就通過詞典搜索希望找到這個詞的定義,如果找到這個詞定義的功能,或者被立即執行,或者作為引用而被編譯到新的定義中。然而,如果在詞典中沒有找到這個詞,系統就試著把它轉換成一個數。如果轉換成功,就把它放在數摞上。如果不能轉換成數字,就顯示這個未定義的詞名並列印出一個錯誤的信息來報告這個詞是系統所不知道的。
漢編詞的執行流程大概可以用一個詞來模擬如下:
編查詞測試
{詞名串--}
255個位元組空給詞名串
詞名串255填0
詞名串字串傳送
詞名串(查詞)
0=
就
計位元組
串>數
就
♀
否則
字串未定義詞名串字串+傳送
詞名串計位元組
回車印字串
全復位
然後
否則
執行
然後
。★
字串看數摞查詞測試數摞已空!★
字串123456查詞測試★.
看數摞[1]123456★.
顯123456★
字串看方法查詞測試
看方法未定義
漢編系統編譯流程如右圖(流程圖來源:漢編新浪博客)所示。
漢編語言堅持「結構化程序設計」原理:
·詞必須在引用之前被定義;
·邏輯流限制只有順序、條件和循環,有專門的詞用於實現常用的程序控制結構;
·程序員使用許多小的、獨立的模塊(詞)來實現最大的可測試性和可靠性;
這種方法有兩個明顯的優點
·新的詞總是用以前定義和測試過的詞來構造,所以調試更容易。模塊可以單獨執行以測試它的功能;
·固有的模塊性使漢編語言成為一個「設計性語言」,允許自頂向下的設計同時保持自底向上的測試。一個詞可以在不同的程序中使用,但是它的功能只需要定義一次;
這些都保證了漢編軟體能夠快速和有效地被開發,同時,如果管理得當,也可以作為自身文檔的基礎。
漢編語言的5個主要元素決定了它的特點:
·一個詞典;
·兩個數摞,一個是參數摞,另一個是用於嵌套的返回摞;
·鍵盤(輸入流)解釋器;
·一個編譯器;
·虛擬存儲; 詞典是漢編定義詞的數據和代碼存儲空間,也為編譯建立了詞的索引。詞典中的詞包括漢編程序代碼詞、常數定義詞、變數定義詞、不定量定義詞,面向對象部分還有模板、對象、對象事件、消息。
漢編代碼存儲在詞典中。詞典占據了系統存儲器的很大部分,它由一個串線鏈接的可變長度的項目組成,每個項目定義了一個詞。每個定義的內容根據詞的類型(數據項、常數、操作序列等)而有所不同,詞典是可擴展的。
詞是由「定義詞」加入詞典的,最常用的定義詞是「編。」當「編」執行的時候,馬上就把後面的詞名掃描,建立一個詞典項,然後進入「編譯」模式。有許多不同的編譯方法,最常用的是「串線編碼」,這種方法把定義編譯成一系列以前定義詞的地址引用。詞的定義由「。」(句號)結束。下面就是一個詞的定義:
編平方(--)♂*顯。
當一個詞名項被編譯到詞典中的時候(稱為定義的首部),它包含一個指向詞典中前一個首部的指針。新詞的詞名加入詞典(這里就是平方),接著一個指向詞名為「(編)」子程序調用的指針編譯到詞典中作為定義的第一部分,這個指針指向一段在解釋定義體時需要執行的代碼。當然,這里所說的不是唯一的編譯技術,但它的應用最為普遍,這種技術稱為間接串線編碼,因為定義中的第一個項目是一段代碼的引用,這段代碼知道如何解釋定義的其它部分。
定義的其它部分稱為這個定義的體。在編譯模式下,系統將依次尋找每個詞的首部。每個首部地址依次放到定義體中,這樣就產生了一個地址列表。最後在到達「。」時,詞名為「。」的子程序地址被編譯進詞典。「。」子程序用來將控制返回到調用詞,就像一個子程序返回一樣。
㈥ 編譯原理詞法分析
編譯的詞法分析,一般是先畫一個狀態轉換圖,一般是有多少分支,就有多少if語句,分支裡面再分(可能有循環語句)。注意記住詞的類別和詞的字元串,請以以下代碼為例,理會一下詞法分析的大致過程。
while(s[i]!='#')
{
while(s[i]==' '||s[i]=='\t'||s[i]=='\n')
{
if(s[i]=='\n')
line++;
i++;
}
if(s[i]=='#')
break;
j=i;
if(s[i]>='a'&&s[i]<='z'||s[i]>='A'&&s[i]<='Z')
{
i++;
while(s[i]>='a'&&s[i]<='z'||s[i]>='A'&&s[i]<='Z'||s[i]>='0'&&s[i]<='9')
i++;
if((i-j)==2&&s[j]=='i'&&s[j+1]=='f')
{
strcpy(dancishuzu[dancigeshu].name,"if");
dancishuzu[dancigeshu].bianhao=4;
dancigeshu++;
}
else if((i-j)==3&&s[j]=='i'&&s[j+1]=='n'&&s[j+2]=='t')
{
strcpy(dancishuzu[dancigeshu].name,"int");
dancishuzu[dancigeshu].bianhao=2;
dancigeshu++;
}
else if((i-j)==3&&s[j]=='f'&&s[j+1]=='o'&&s[j+2]=='r')
{
strcpy(dancishuzu[dancigeshu].name,"for");
dancishuzu[dancigeshu].bianhao=6;
dancigeshu++;
}
else if((i-j)==4&&s[j]=='m'&&s[j+1]=='a'&&s[j+2]=='i'&&s[j+3]=='n')
{
strcpy(dancishuzu[dancigeshu].name,"main");
dancishuzu[dancigeshu].bianhao=1;
dancigeshu++;
}
else if ((i-j)==4&&s[j]=='c'&&s[j+1]=='h'&&s[j+2]=='a'&&s[j+3]=='r')
{
strcpy(dancishuzu[dancigeshu].name,"char");
dancishuzu[dancigeshu].bianhao=3;
dancigeshu++;
}
else if ((i-j)==4&&s[j]=='e'&&s[j+1]=='l'&&s[j+2]=='s'&&s[j+3]=='e')
{
strcpy(dancishuzu[dancigeshu].name,"else");
dancishuzu[dancigeshu].bianhao=5;
dancigeshu++;
}
else if ((i-j)==5&&s[j]=='w'&&s[j+1]=='h'&&s[j+2]=='i'&&s[j+3]=='l'&&s[j+4]=='e')
{
strcpy(dancishuzu[dancigeshu].name,"while");
dancishuzu[dancigeshu].bianhao=7;
dancigeshu++;
}
else{
dancishuzu[dancigeshu].bianhao=10;
count=0;
while(j<i)
{
dancishuzu[dancigeshu].name[count++]=s[j];
j++;
}
dancishuzu[dancigeshu].name[count]='\0';
dancigeshu++;
}
}
else if(s[i]>='0'&&s[i]<='9')
{
while(s[i]>='0'&&s[i]<='9')
i++;
dancishuzu[dancigeshu].bianhao=11;
count=0;
while(j<i)
{
dancishuzu[dancigeshu].name[count++]=s[j];
j++;
}
dancishuzu[dancigeshu].name[count]='\0';
dancigeshu++;
}
else if(s[i]=='=')
{
if(s[i+1]=='=')
{
dancishuzu[dancigeshu].bianhao=30;
strcpy(dancishuzu[dancigeshu].name,"==");
dancigeshu++;
i+=2;
}
else
{
dancishuzu[dancigeshu].bianhao=12;
strcpy(dancishuzu[dancigeshu].name,"=");
dancigeshu++;
i++;
}
}
else if(s[i]=='+')
{
dancishuzu[dancigeshu].bianhao=13;
strcpy(dancishuzu[dancigeshu].name,"+");
dancigeshu++;
i++;
}
else if(s[i]=='-')
{
dancishuzu[dancigeshu].bianhao=14;
strcpy(dancishuzu[dancigeshu].name,"-");
dancigeshu++;
i++;
}
else if(s[i]=='*')
{
dancishuzu[dancigeshu].bianhao=15;
strcpy(dancishuzu[dancigeshu].name,"*");
dancigeshu++;
i++;
}
else if(s[i]=='/')
{
dancishuzu[dancigeshu].bianhao=16;
strcpy(dancishuzu[dancigeshu].name,"/");
dancigeshu++;
i++;
}
else if(s[i]=='(')
{
i++;
dancishuzu[dancigeshu].bianhao=17;
strcpy(dancishuzu[dancigeshu].name,"(");
dancigeshu++;
}
else if(s[i]==')')
{
i++;
dancishuzu[dancigeshu].bianhao=18;
strcpy(dancishuzu[dancigeshu].name,")");
dancigeshu++;
}
else if(s[i]=='[')
{
i++;
dancishuzu[dancigeshu].bianhao=19;
strcpy(dancishuzu[dancigeshu].name,"[");
dancigeshu++;
}
else if(s[i]==']')
{
i++;
dancishuzu[dancigeshu].bianhao=20;
strcpy(dancishuzu[dancigeshu].name,"]");
dancigeshu++;
}
else if(s[i]=='{')
{
i++;
dancishuzu[dancigeshu].bianhao=21;
strcpy(dancishuzu[dancigeshu].name,"{");
dancigeshu++;
}
else if(s[i]=='}')
{
i++;
dancishuzu[dancigeshu].bianhao=22;
strcpy(dancishuzu[dancigeshu].name,"}");
dancigeshu++;
}
else if(s[i]==',')
{
i++;
dancishuzu[dancigeshu].bianhao=23;
strcpy(dancishuzu[dancigeshu].name,",");
dancigeshu++;
}
else if(s[i]==':')
{
i++;
dancishuzu[dancigeshu].bianhao=24;
strcpy(dancishuzu[dancigeshu].name,":");
dancigeshu++;
}
else if(s[i]==';')
{
i++;
dancishuzu[dancigeshu].bianhao=25;
strcpy(dancishuzu[dancigeshu].name,";");
dancigeshu++;
}
else if(s[i]=='>')
{
if(s[i+1]=='=')
{
dancishuzu[dancigeshu].bianhao=28;
strcpy(dancishuzu[dancigeshu].name,">=");
dancigeshu++;
i+=2;
}
else
{
i++;
dancishuzu[dancigeshu].bianhao=26;
strcpy(dancishuzu[dancigeshu].name,">");
dancigeshu++;
}
}
else if(s[i]=='<')
{
if(s[i+1]=='=')
{
dancishuzu[dancigeshu].bianhao=29;
strcpy(dancishuzu[dancigeshu].name,"<=");
dancigeshu++;
i+=2;
}
else
{
i++;
dancishuzu[dancigeshu].bianhao=27;
strcpy(dancishuzu[dancigeshu].name,"<");
dancigeshu++;
}
}
else if(s[i]=='!'&&s[i+1]=='=')
{
dancishuzu[dancigeshu].bianhao=31;
strcpy(dancishuzu[dancigeshu].name,"!=");
dancigeshu++;
i+=2;
}
else
{
printf("\nline:%derror!",line);
i++;
return;
}
}
㈦ 求C語言編譯原理語法分析程序
一繼承的詞法來自
http://blog.sina.com.cn/s/blog_67c9fc300100srad.html
二語法
用擴充的BNF表示如下:
⑴<程序>::=begin<語句串>end
⑵<語句串>::=<語句>{;<語句>}
⑶<語句>::=<賦值語句>
⑷<賦值語句>::=ID:=<表達式>
⑸<表達式>::=<項>{+<項> | -<項>}
⑹<項>::=<因子>{*<因子> | /<因子>
⑺<因子>::=ID | NUM | (<表達式>)
三要求
輸入單詞串,以「#」結束,如果是文法正確的句子,則輸出成功信息,列印「success」,否則輸出「error」。
例如:
輸入 begin a:=9; x:=2*3; b:=a+x end #
輸出 success!
輸入 x:=a+b*c end #
輸出 error!
㈧ 編譯原理: 畫出識別如下單詞的狀態轉換圖: Char int float
(四)練習該實驗的目的和思路: 程序開始變得復雜起來,可能是大家以前編過的程序中最復雜的,但相對於 以後的程序來說還是簡單的。因此要認真把握這個過渡期的練習。程序規模 大概為 200 行及以上。通過練習,掌握對字元進行靈活處理的方法。 (五)為了能設計好程序,注意以下事情: 1.模塊設計:將程序分成合理的多個模塊(函數/類) ,每個模塊(類)做具 體的同一事情。 2.寫出(畫出)設計方案:模塊關系簡圖、流程圖、全局變數、函數介面等。 3.編程時注意編程風格:空行的使用、注釋的使用、縮進的使用等。 4.程序設計語言不限,建議使用面向對象技術及可視化編程語言,如 C++, VC,JAVA,VJ++等。
四、上交:
1.程序源代碼及可執行文件(當堂檢查/通過網路提交) ; 2.已經測試通過的測試數據 3 組(全部存在一個文本文件中,以「第一組輸 入/輸出/第二組輸入/輸出/第三組輸入/輸出」的順序存放) ; 3.實驗報告按照提供的模板填寫: (1) 功能描述:該程序具有什麼功能? (2) 演算法描述:所採用的數據結構,基本實現演算法及某些特殊過程的實 現演算法(如在處理某個問題時,你所採取的好的處理方法等)注意 此處不要簡單的將源程序抄上來。 (源程序將列印出來作為附錄) (3) 程序結構描述:函數調用格式、參數含義、返回值描述、函數功能; 另外可以附加函數之間的調用關系圖、 程序總體執行流程圖及類的 層次圖。 (4) 實驗總結:你在編程過程中花時多少?多少時間在紙上設計?多少 時間上機輸入和調試?多少時間在思考問題?遇到了哪些難題?你 是怎麼克服的?你對你的程序的評價?你的收獲有哪些? (5) 寫出上機調試時發現的問題,以及解決的過程; (6) 附上源程序(列印的)
㈨ C語言編譯執行的全過程是怎樣的
不明白樓主什麼意思,就是先把你的代碼轉為匯編代碼,然後轉為二進制文件,讀入內存執行。