❶ C語言編程題目 循環語句 請詳細說明循環步驟
你的語句while(n++<=2);後面有分號,表示執行空語句(空語句是指語句為空,什麼都不做),如果沒有分號的話,就是執行printf("%d",n);就能說明是一個while循環語句了。
你要看清楚,寫循環語句時,是這樣的形式:
while(表達式) 語句;(注意分號的位置)
如果你的程序是這樣的:
int n=0;
while(n++<=2)
printf("%d",n);
分析:n=0,n<2,執行printf("%d",n),然後n++使得n=1;
n=1,n<2,執行printf("%d",n),然後n++使得n=2;
n=2,n<2為假,跳出循環。
輸出結果:1 2
如果你的程序是這樣的:
int n=0;
while(n++<=2);
printf("%d",n);
分析:n=0,n<2,然後n++使得n=1;
n=1,n<2,然後n++使得n=2;
n=2,n<2為假,跳出循環。
最後執行printf("%d",n),輸出2
輸出結果:2
❷ c語言編程題for循環語句
代碼如下:
# include < stdio.h >
Voidmain()
{
Int[100].
Ints=0,I,num,Max,min,av;
Printf("enternumberofstudents:");
Thescanf("%d",num);
Printf("inputfraction\n");
(I = 0; The < num; + +)
{printf("%d:",I+1);
Scanf("%d",and[I]);}
(I = 0; The < num; + +)
Printf("%4d",[I]);
Printf("\n");
Max=[0];
Min=[0];
(I = 0; The < num; + +)
S=s+[I];
Av=s/10;
(I = 0; The < num; + +)
{if ([I]> Max) Max =[I];
If ([I]< min) minutes =[I];
}
Printf("Max=%d,min=%d,assertion=%d\n",Max,min,av);
}
(2)循環語句詞法分析編譯程序擴展閱讀:
For循環是編程語言中的一種循環語句,循環語句由循環體和循環的判斷條件組成,其表達式為:For(單表達式;條件表達式;(循環體){中間循環體;}。
1.這句話最簡單的形式是:
(;,)
2.一般形式為:
(單一的表達式;條件表達式;結束循環體)
{
Mesocycle;
}
式中,表達式可以省略,但分號不能省略,因為「;」可以表示一個空的語句,省略後語句減少,即語句格式發生變化,編譯器無法識別和編譯。[1]
第一」;「前面的for循環括弧中是一個不參與循環的表達式,可以用作變數的初始賦值語句,將初始值賦給循環控制變數;您還可以計算其他獨立於for循環但在循環部分之前處理的表達式。
」;「符號之間的條件表達式是一個關系表達式,它是循環的正式開始,在建立條件表達式時執行中間循環的主體。
執行的中間循環體可以是一條語句,也可以是多條語句。當中間的循環體只有一條語句時,可以省略大括弧{}。在執行中間循環體之後,執行最終循環體。
在執行最後一個循環體之後,將再次執行條件判斷。如果條件仍然有效,則會重復上面的循環,如果條件無效,則會中斷當前的for循環。
❸ 程序開發中循環語句for詳解
首先for循環語句是程序中性能最高的循環之一,我一般都用它。
for 有兩種形式:一種是數字形式,另一種是通用形式。
數字形式的 for 循環,通過一個數學運算不斷地運行內部的代碼塊。 下面是它的語法:
block 將把 name 作循環變數。 從第一個 exp 開始起,直到第二個 exp 的值為止, 其步長為第三個 exp 。 更確切的說,一個 for 循環看起來是這個樣子
注意下面這幾點:
所有三個控製表達式都只被運算一次, 表達式的計算在循環開始之前。 這些表達式的結果必須是數字。
var,limit,以及 step 都是一些不可見的變數。 這里給它們起的名字都僅僅用於解釋方便。
如果第三個表達式(步長)沒有給出,會把步長設為 1 。
你可以用 break 和 goto 來退出 for 循環。
循環變數 v 是一個循環內部的局部變數; 如果你需要在循環結束後使用這個值, 在退出循環前把它賦給另一個變數。
通用形式的 for 通過一個叫作 迭代器 的函數工作。 每次迭代,迭代器函數都會被調用以產生一個新的值, 當這個值為 nil 時,循環停止。 通用形式的 for 循環的語法如下:
注意以下幾點:
explist 只會被計算一次。 它返回三個值, 一個 迭代器 函數, 一個 狀態, 一個 迭代器的初始值。
f, s,與 var 都是不可見的變數。 這里給它們起的名字都只是為了解說方便。
你可以使用 break 來跳出 for 循環。
環變數 var_i 對於循環來說是一個局部變數; 你不可以在 for 循環結束後繼續使用。 如果你需要保留這些值,那麼就在循環跳出或結束前賦值到別的變數里去。
到第二個 exp 的值為止, 其步長為第三個 exp 。 更確切的說,一個 for 循環看起來是這個樣子
注意下面這幾點:
所有三個控製表達式都只被運算一次, 表達式的計算在循環開始之前。 這些表達式的結果必須是數字。
var,limit,以及 step 都是一些不可見的變數。 這里給它們起的名字都僅僅用於解釋方便。
如果第三個表達式(步長)沒有給出,會把步長設為 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)
可以用語法圖來表示語言的文法,如圖:
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 年月日
❺ 這里有一個c語言的語法分析程序,該怎麼使用,我想得到它的語法樹,然後在上面提取循環語句信息
在計算機科學中,抽象語法樹(abstract syntax tree或者縮寫為AST),或者語法樹(syntax tree),是源代碼的抽象語法結構的樹狀表現形式,這里特指編程語言的源代碼。樹上的每個節點都表示源代碼中的一種結構。之所以說語法是「抽象」的,是因為這里的語法並不會表示出真實語法中出現的每個細節。比如,嵌套括弧被隱含在樹的結構中,並沒有以節點的形式呈現;而類似於if-condition-then這樣的條件跳轉語句,可以使用帶有兩個分支的節點來表示。和抽象語法樹相對的是具體語法樹(concrete syntaxtree),通常稱作分析樹(parse tree)。一般的,在源代碼的翻譯和編譯過程中,語法分析器創建出分析樹。一旦AST被創建出來,在後續的處理過程中,比如語義分析階段,會添加一些信息。
❻ C語言編程循環語句請詳細說明循環步驟
scanf("%d%d",&a,&b);
long result;
result=a*a+b*b;
if(result>100)
{
int s;
s=result/100;
while(s!=0)
{
int t;
t=s%10;
s=s/10;
printf("%d ",t);
}
}else
{
long f;
f=a+b;
printf("%ld ",f);
}
循環步驟:
1.初始化循環偏移量,本題中while循環里的s的初始化是int s; s=result/100;(這個操作只操作一次,就是在剛進循環的時候,後面都是按一定規律去改變這個偏移量)。
2.判定條件是否符合 就是while括弧里的條件,本題中是判斷s是否等於0了,
3.符合條件的話,就進入循環體,
4.做完需要的操作時,就把偏移量按一定的規律改變他的值,本題中是s=s/10;
5.再判斷條件是否符合,本題中是判斷s是否符合s不等於0,如果符合條件,再次進入循環體,這樣就形成了一個循環,偏移量一直按一定規律改變自身的值,一直到他的值不符合條件才跳出循環
❼ 急求高人編寫一個簡單的詞法分析程序
嘿嘿,這個我做過哦。是編譯原理的東西。
不過現在沒有程序,沒帶來,給你一個參考的:雖然不是完全符合你的要求。不過其中很多函數你是要用到的,比如詞法分析部分,其實你的要求就是進行詞法分析的,無非你用scanf(),你用詞法分析,分析出scanf()語句,再進行內部參數分析,就OK了;
祝你成功哦
///////////////////////////////////////////////////////////////////
for循環語句翻譯 遞歸下降法 輸出三地址碼 /////////////
#define MAX 100
#include<iostream.h>
#include<stdio.h>
#include<string.h>
char str[MAX];
char ch;
int turn;
char strToken[MAX];
int kind;
int n=0;//存放strtoken[]元素的個數
struct Word//結構體 存放單詞
{
int sort;
char word[MAX];//存放strtoken[]的內容
};
//record[x]=new Word;
Word *record[12];//放所有識別出來的單詞,分別存放他們的編號以及字元串,x是其下標
////////////////////詞法分析///////////////////////
int buffer()//載入
{
int i=0;
cout<<"輸入程序,以「#」作為結束標志。"<<endl;
for(int n=0;n<=MAX;n++)
{
for(;i<=MAX;i++)
{
scanf("%c",&str[i]);
/////////////cin>>str[i]不可用,用C語言讀入字元。
if(str[i]=='#')
break;///////如果尾數為識別碼#,則表示程序讀完,跳出循環.
}
break;
}
return(i);
}
bool IsLetter(char ch)///////////判斷是否是字母
{
if(ch>=65&&ch<=90||ch>=97&&ch<=122)
return(true);
else
return(false);
}
bool IsDigit(char ch)//////////判斷是否是數字
{
if(ch>=48&&ch<=57)
return(true);
else
return(false);
}
char GetChar(int i)///////讀取字元
{
char ch;
ch=str[i];
return(ch);
}
char GetBC(char ch)////判斷是不是空格或者換行,如果是,直接讀取下一個字元直道不再空白為止
{
if(ch==32||ch==10)
{
turn++;
ch=GetChar(turn);
ch=GetBC(ch);/////////遞歸實現
return(ch);
}
else
return(ch);
}
void Concat()/////////////連接,即為strtoken[]賦值
{
strToken[n]=ch;
n++;
}
int Reserve()/////以單詞為單位查找保留字,是則返回編碼,不是則返回0,用來區分標志符和保留字
{
if(strcmp(strToken," DIM\0")==0)///////調用strcmp函數實現,
return(1);
else if(strcmp(strToken,"for\0")==0)
return(2);
else if(strcmp(strToken,"step\0")==0)
return(3);
else if(strcmp(strToken,"until\0")==0)
return(4);
else if(strcmp(strToken,"do\0")==0)
return(5);
else
return(6);
}
void clear()
{
n=0;
}
/////////////*語法遞歸分析*/////////////////
int A(int * c,int & q)
{
if(c[q++]==3)
{
if(c[q]==7)
{ q++;
return 1;
}
else {cout<<"step右部出錯"<<endl;return 0;}
}else {cout<<"error 'step'"<<endl;return 0;}
}
int B(int * b,int & o)
{
if(b[o++]==4)
{
if(b[o]==7)
{ o++;
return 1;
}
else {cout<<"until右部出錯"<<endl;return 0;}
}else {cout<<"error 'until'"<<endl;return 0;}
}
int S2(int * d,int & h)
{
if(d[h++]==6)
{
if(d[h++]==8)
{
if((d[h]==6||d[h]==7)) {h++; return 1;}
else {cout<<"賦值語句右部出錯 "<<endl;return 0;}
}else {cout<<"賦值語句缺少賦值運算符 "<<endl;return 0;}
}else {cout<<"賦值語句左部出錯 "<<endl;return 0;}
}
int S1(int * m,int & n)
{
if(S2(m,n))
{
if(A(m,n))
{
if(B(m,n)) return 1;
else return 0;
}else return 0;
}else return 0;
}
int S(int *a,int & z)
{
if (a[z++]==2)
{
if (S1(a,z))
{
if(a[z++]==5)
{
if(S2(a,z))
{
cout<<"succeed!"<<endl;return 1;
}else return 0;
}else {cout<<"error 'do'"<<endl; return 0;}
}else return 0;
}else {cout<<"error 'for'"<<endl; return 0;}
}
void main()
{
cout<<"*************產生式***************"<<endl;// for step until do i j =
cout<<" S ->for S1 do S2"<<endl; // 編號 2 3 4 5 6 7 8
cout<<" S1 ->S2AB"<<endl;
cout<<" S2 ->i=j"<<endl;
cout<<" A ->stepj"<<endl;
cout<<" B ->untilj"<<endl;
int num;
turn=0;
num=buffer()-1;
int x=0;//計識別的單詞的個數
for(;turn<=num;turn++)//總循環,ch存放剛讀入的字元,strtoken[]存放已識別的標志付或保留字,turn是數組str[]的下標
{
ch=GetChar(turn);
ch=GetBC(ch);
if(IsLetter(ch))
{
while(IsLetter(ch)&&turn<=num||IsDigit(ch)&&turn<=num)
{
Concat();
ch=GetChar(++turn);
}
strToken[n]='\0';
ch=NULL;//此ch不是標志符中的符號
turn=turn-1;
kind=Reserve();
record[x]=new Word; record[x]->sort=kind;//12345或6
//cout<<kind; //測試
cout<<"(";
for(int i=0;i<n;i++)
{
record[x]->word[i]=strToken[i];
cout<<record[x]->word[i];//輸出識別的標志符或保留字
}
cout<<","<<kind<<")"<<endl;
record[x]->word[i]='\0';
clear();
x++;
}
else if(IsDigit(ch))
{
while(IsDigit(ch)&&turn<=num)
{
Concat();
ch=GetChar(++turn);
}
ch=NULL;
turn=turn-1;
kind=7;
//////////////
record[x]=new Word;
record[x]->sort=kind;
////////////////
cout<<"(";
for(int i=0;i<n;i++)
{
record[x]->word[i]=strToken[i];
cout<<record[x]->word[i];
}
cout<<","<<kind<<")"<<endl;
record[x]->word[i]='\0';
clear();x++;
}
else if(ch=='=')
{
kind=8;
///////
record[x]=new Word;
record[x]->word[0]='=';
record[x++]->sort=kind;
cout<<"(=,"<<kind<<")"<<endl;
}
else
cout<<"error input!"<<endl;
}
//////////////////////*語法分析*////////////////
//int y;
/*for(y=0;y<x;y++)
{cout<<record[y]->sort<<" ";//列印單詞的編號 。
}cout<<endl;*/
int ana[MAX];//存放詞法分析得到的單詞序列的編號的序列
int m;
for(m=0;m<x;m++)
{
ana[m]=record[m]->sort;//將sort作為數組保存起來
}
/////////語法分析///////
int j=0;
///////////////////制導翻譯//////////////////
if(!S(ana,j)) cout<<"語法出錯!"<<endl;
else
{ cout<<"三地址碼如下:"<<endl;
cout<<"100 ";
int i=0;
while(record[1]->word[i]!='\0')
cout<<record[1]->word[i++];cout<<record[2]->word[0];
i=0;
while(record[3]->word[i]!='\0')
cout<<record[3]->word[i++];cout<<endl;
cout<<"101 goto 103"<<endl;
cout<<"102 ";
i=0;
while(record[1]->word[i]!='\0')
cout<<record[1]->word[i++];cout<<":=";
i=0;
while(record[1]->word[i]!='\0')
cout<<record[1]->word[i++];cout<<"+";
i=0;
while(record[5]->word[i]!='\0')
cout<<record[5]->word[i++];cout<<endl;
cout<<"103 if ";
i=0;
while(record[1]->word[i]!='\0')
cout<<record[1]->word[i++];cout<<"<";
i=0;
while(record[7]->word[i]!='\0')
cout<<record[7]->word[i++];
cout<<" goto 105"<<endl;
cout<<"104 goto 107"<<endl;
cout<<"105 ";
i=0;
while(record[9]->word[i]!='\0')
cout<<record[9]->word[i++];cout<<":=";
i=0;
while(record[11]->word[i]!='\0')
cout<<record[11]->word[i++];cout<<endl;
cout<<"106 goto 102"<<endl;
cout<<"107 end"<<endl;
}
}
❽ 3.3 循環語句 (1) 預測下列程序的運行結果,然後編譯、執行該程序以驗證你的預測: class JLab0303_1{ p
共執行三次
當外層循環變數i=1時 不執行
i=2時 執行了1次
i=3時 執行了2次
所以總共執行了3次
❾ 編譯原理課程設計--FOR循環語句的翻譯程序設計
暈,大哥你好懶,這都不自己寫
❿ 編譯程序有哪些主要構成成分它們各自的主要功能是什麼
編譯過程分為分析和綜合兩個部分,並進一步劃分為詞法分析、語法分析、語義分析、代碼優化、存儲分配和代碼生成等六個相繼的邏輯步驟。這六個步驟只表示編譯程序各部分之間的邏輯聯系,而不是時間關系。
編譯過程既可以按照這六個邏輯步驟順序地執行,也可以按照平行互鎖方式去執行。在確定編譯程序的具體結構時,常常分若干遍實現。對於源程序或中間語言程序,從頭到尾掃視一次並實現所規定的工作稱作一遍。每一遍可以完成一個或相連幾個邏輯步驟的工作。
例如,可以把詞法分析作為第一遍;語法分析和語義分析作為第二遍;代碼優化和存儲分配作為第三遍;代碼生成作為第四遍。
反之,為了適應較小的存儲空間或提高目標程序質量,也可以把一個邏輯步驟的工作分為幾遍去執行。例如,代碼優化可劃分為代碼優化准備工作和實際代碼優化兩遍進行。
(10)循環語句詞法分析編譯程序擴展閱讀
從左至右逐個字元地對源程序進行掃描,產生一個個的單詞符號,把作為字元串的源程序改造成為單詞符號串的中間程序。執行詞法分析的程序稱為詞法分析程序或掃描器。
源程序中的單詞符號經掃描器分析,一般產生二元式:單詞種別;單詞自身的值。單詞種別通常用整數編碼,如果一個種別只含一個單詞符號,那麼對這個單詞符號,種別編碼就完全代表它自身的值了。若一個種別含有許多個單詞符號,那麼,對於它的每個單詞符號,除了給出種別編碼以外,還應給出自身的值。
詞法分析器一般來說有兩種方法構造:手工構造和自動生成。手工構造可使用狀態圖進行工作,自動生成使用確定的有限自動機來實現。
編譯程序的語法分析器以單詞符號作為輸入,分析單詞符號串是否形成符合語法規則的語法單位,如表達式、賦值、循環等,最後看是否構成一個符合要求的程序,按該語言使用的語法規則分析檢查每條語句是否有正確的邏輯結構,程序是最終的一個語法單位。編譯程序的語法規則可用上下文無關文法來刻畫。