生活随笔
收集整理的這篇文章主要介紹了
递归下降分析法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
根據文法:
E→E+T|E-T|T
T→T*F| T/F|F
F→(E)|i
1 #include<stdio.h>
2 #include<
string.h>
3 #include<stdlib.h>
4 char TOken[
10];
//分開進行比較
5 char ch;
6 char r1[]={
"begin"};
7 char r2[]={
"if"};
8 char r3[]={
"then"};
9 char r4[]={
"while"};
10 char r5[]={
"do"};
11 char r6[]={
"end"};
12 char r7[]={
"break"};
13 char r8[]={
"case"};
14 char r9[]={
"main"};
15 char r10[]={
"l(l|d)*"};
16 char r11[]={
"dd*"};
17 char r12[]={
"="};
18 char r13[]={
"+"};
19 char r14[]={
"-"};
20 char r15[]={
"*"};
21 char r16[]={
"/"};
22 char r17[]={
":"};
23 char r18[]={
"{"};
24 char r19[]={
"}"};
25 char r20[]={
"<"};
26 char r21[]={
"!="};
27 char r22[]={
"<="};
28 char r23[]={
">"};
29 char r24[]={
">="};
30 char r25[]={
"=="};
31 char r26[]={
"("};
32 char r27[]={
")"};
33 char r28[]={
"="};
34 char r29[]={
"--"};
35 char r30[]={
"++"};
36 char r31[]={
"!"};
37 char r32[]={
":="};
38 char r33[]={
";"};
39 char r34[]={
"."};
40 char A[
10000];
//輸入的所有值
41 int syn,row;
42 int n,m,p,sum,j;
43 static int i =
0;
44 void scaner();
45 void E ();
46 void E1();
47 void T ();
48 void T1();
49 void F ();
50 int main()
51 {
52 row =
0 ;
53 p =
0 ;
54 printf(
"符號與種別碼對照表如下:\n");
55 printf(
" 單詞符號 種別碼 單詞符號 種別碼\n");
56 printf(
" begin 1 : 17\n");
57 printf(
" if 2 { 18\n");
58 printf(
" then 3 } 19\n");
59 printf(
" while 4 < 20\n");
60 printf(
" do 5 != 21\n");
61 printf(
" end 6 <= 22\n");
62 printf(
" break 7 > 23\n");
63 printf(
" case 8 >= 24\n");
64 printf(
" main 9 == 25\n");
65 printf(
" l(l|d)* 10 ( 26\n");
66 printf(
" dd* 11 ) 27\n");
67 printf(
" = 12 = 28\n");
68 printf(
" + 13 -- 29\n");
69 printf(
" - 14 ++ 30\n");
70 printf(
" * 15 ! 31\n");
71 printf(
" / 16 := 32\n");
72 printf(
" @ 0 ; 33\n\n");
73 printf(
" 請輸入您想轉換的語句(輸入@結束):\n");
74 do{
75 scanf(
"%c",&
ch);
76 A[p]=
ch;
77 p++
;
78 }
while(ch!=
'@');
/*將輸入的語句分別存入數組A[]中,@出現時結束語句*/
79 p=
0;
80 do
81 {
82 scaner();
//進入函數進行判定
83 switch(syn)
84 {
85 case 11: printf(
"(%d,%d)\n",syn,sum);
break;
//如果是11,那么就是數字
86 case -
2: row=row++;
break;
87 default: printf(
"(%d,%s)\n",syn,TOken);
break;
//否則,就是變量名、關鍵詞
88 }
89 }
while (syn!=
0);
90 system(
"pause");
91 p=
0;
92 scaner();
93 E();
94 if (syn==
0)
95 printf(
"\n 語法正確. \n");
96 else
97 printf(
"\n 語法錯誤. \n");
98
99 }
100 void scaner()
/*分別對標示符、數字、符號進行分析*/
101 {
102 for(n=
0;n<
10;n++
)
103 TOken[n]=
0;
/*每次循環完就清零*/
104 m=
0;
105 sum=
0;
106 ch=
A[i];
107 while(ch==
' '||ch==
'\n')
/*如果字符是空格或者回車,跳過*/
108 {
109 i++
;
110 ch=
A[i];
111 }
112 if((ch>=
'a'&&ch<=
'z')||(ch>=
'A'&&ch<=
'Z'))
/*如果是標示符或者變量名,循環尋找*/
113 {
114 m=
0;
115 while((ch>=
'0'&&ch<=
'9')||(ch>=
'a'&&ch<=
'z')||(ch>=
'A'&&ch<=
'Z'))
/*找到一個變量名或者關鍵字,直到遇到空格為止*/
116 {
117 TOken[m]=ch;m++
;
118 i++;ch=
A[i];
119 }
120 TOken[m]=
'\0';
/*將識別出來的字符和已定義的標示符作比較,輸出其種別碼*/
121 if(strcmp(TOken,r1)==
0){syn=
1;}
122 else if(strcmp(TOken,r2)==
0){syn=
2;}
123 else if(strcmp(TOken,r3)==
0){syn=
3;}
124 else if(strcmp(TOken,r4)==
0){syn=
4;}
125 else if(strcmp(TOken,r5)==
0){syn=
5;}
126 else if(strcmp(TOken,r6)==
0){syn=
6;}
127 else if(strcmp(TOken,r7)==
0){syn=
7;}
128 else if(strcmp(TOken,r8)==
0){syn=
8;}
129 else if(strcmp(TOken,r9)==
0){syn=
9;}
130
131 else{syn=
10;}
132 }
133 else if((ch>=
'0'&&ch<=
'9'))
//數字
134 {
135 sum=
0;
136 while((ch>=
'0'&&ch<=
'9'))
137 {
138 sum=sum*
10+ch-
'0';
//顯示其對應數字sum
139 i++
;
140 ch=
A[i];
141 }
142 syn=
11;
143 }
144 else switch(ch)
//有兩個的字符
145 {
146 case'<':m=
0;TOken[m]=ch;m++
;
147 i++;ch=
A[i];
148 if(ch==
'=')
149 {
150 syn=
22;
//<=
151 TOken[m]=ch;m++;i++
;
152 }
153 else{syn=
20;}
break;
//<
154
155 case'>':m=
0;TOken[m]=ch;m++
;
156 i++;ch=
A[i];
157 if(ch==
'='){
158 syn=
24;
//>=
159 TOken[m]=ch;m++;i++
;
160 }
161 else{syn=
23;}
break;
//>
162
163 case':':m=
0;TOken[m]=ch;m++
;
164 i++;ch=
A[i];
165 if(ch==
'=')
166 {
167 syn=
32;
//:=
168 TOken[m]=ch;m++;i++
;
169 }
170 else
171 {syn=
17;}
break;
//:
172
173 case'@':syn=
0;TOken[
0]=ch;
break;
174 case'=':syn=
12;TOken[
0]=ch;
break;
175 case'+':syn=
13;TOken[
0]=ch;
break;
176 case'-':syn=
14;TOken[
0]=ch;
break;
177 case'*':syn=
15;TOken[
0]=ch;
break;
178 case'/':syn=
16;TOken[
0]=ch;
break;
179 case'{':syn=
18;TOken[
0]=ch;
break;
180 case'}':syn=
19;TOken[
0]=ch;
break;
181 case'(':syn=
26;TOken[
0]=ch;
break;
182 case')':syn=
27;TOken[
0]=ch;
break;
183 case';':syn=
33;TOken[
0]=ch;
break;
184 case'.':syn=
34;TOken[
0]=ch;
break;
185 // case'\n':syn=-2;break;
186 default: syn=-
1;TOken[
0]=
ch;
187 }
188 }
189 /*以下函數分別對應于子模塊程序*/
190
191 void E(){
192 printf(
"E ");
193 T();
194 E1();
195 }
196
197 void E1(){
198 printf(
"E1 ");
199 if(syn==
13||syn==
14){
200 scaner();
201 T();
202 E1();
203 }
204 else {
205 if (syn!=
27 && syn!=
0)
206 printf(
"\n (%d,%s)語法錯誤! \n",syn, TOken);
207 }
208 }
209
210 void T(){
211 printf(
"T ");
212 F();
213 T1();
214 }
215
216 void T1(){
217 printf(
"T1 ");
218 if(syn==
15||syn==
16){
219 scaner();
220 F();
221 T1();
222 }
223 else{
224 if(syn!=
0&&syn!=
28&&syn!=
13&&syn!=
14)
225 printf(
"\n (%d,%s)語法錯誤! \n",syn, TOken);
226 }
227 }
228
229 void F(){
230 printf(
"F ");
231 if(syn==
10||syn==
11)
232 {
233 scaner();
234 }
235 else if(syn==
26)
236 {
237 scaner();
238 E();
239 if(syn==
27){
240 scaner();
241 }
242 else
243 printf(
"\n (%d,%s)語法錯誤! \n",syn, TOken);
244 }
245
246 }
?
轉載于:https://www.cnblogs.com/oechen/p/6209734.html
總結
以上是生活随笔為你收集整理的递归下降分析法的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。