1樓:匿名使用者
目 錄
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)
可以用語法圖來表示語言的文法,如圖:et
f3.2中間**形式描述
中間**採用四元式輸出,一個四元式是一個帶有四個域的記錄結構,這四個域分別稱為op﹑arg1﹑arg2及result。域op包含一個代表運算子的內部碼。語句while a100 ( <, a , b , 102 )
101 ( j , _ , _ , 105 )
102 ( + , a , b , n )
103 ( = , n , _ , a )
104 ( j , _ , _ , 100)
1054.簡要的分析與概要設計
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 查錯
按照遞迴下降法求wawedg\n",total);total++;
w();
e();
}w()
void w()
}e()
void e()
printf("%d\te-->afb\n",total);total++;
f();
}f()
void f()
switch(ch)
d();
g();
}d()
void d()
ch=a[++i1];
}g()
void g()
printf("%d\tg-->c=r\n",total);total++;
r();
}r()
void r()
else
else}}
t()void t()
ch='#';
}6測試方法和測試結果
6.1測試方法
在c++環境下,設計幾個有代表的用例,進行測試,例如:輸入語句wa
#include
#include
#include
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()
while(ch!='#');
n1=j;
ch=a[0];
s();
printf("\n");
if (ch=='#')
else
printf("\n");
printf("press any key to continue..\n");
getchar();
getchar();
}/*出錯情況分析*/
void s()
void w()
}void e()
printf("%d\te-->afb\n",total);total++;
f();
}void f()
switch(ch)
d();
g();
}void d()
ch=a[++i1];
}void g()
printf("%d\tg-->c=r\n",total);total++;
r();
}void r()
else
else}}
void t()
ch='#';
}指導教師簽名:
2010 年 月 日
在c語言中有哪幾種用於實現迴圈結構程式設計的語句,分別寫出它們的語法格式並比較它們的用法
2樓:匿名使用者
for ; do while ;while do; for和while do 語句都是先判斷後執行 ,do while 語句是先執行後判斷 所以會 不管條件滿足與否 先執行一次迴圈