语法分析器在词法分析器的基础上增加了递归下降分析程序,咱也不知道啥是递归下降程序,咱也不想问。
但是有程序框图和伪代码把程序跑通咱还是比较在行滴。为了便于理解,debug过程中的输出也保留了。
下面是完整代码。
1 /* 2 begin a:= 9; x:=2*3;b:=a+x end# 3 x:= a+b*c end # 4 */ 5 #include6 #include 7 #include <string.h> 8 #define _KEY_WORD_END "waiting for your expanding" 9 typedef struct 10 { 11 int typenum; 12 char *word; 13 }WORD; 14 char input[255]; 15 char token[255]=""; 16 int p_input; 17 int p_token; 18 char ch; 19 char* rwtab[] = {"begin","if","then","while","do","end",_KEY_WORD_END}; 20 WORD * scaner(); 21 WORD* oneword = new WORD; 22 int syn,kk; 23 void expression(); 24 void factor() 25 { 26 if(syn == 10 || syn == 11) 27 { 28 oneword = scaner(); 29 syn = oneword->typenum; 30 printf("%s %d\n",oneword->word,syn); 31 } 32 else if(syn == 27) 33 { 34 oneword = scaner(); 35 syn = oneword->typenum; 36 printf("%s %d\n",oneword->word,syn); 37 expression(); 38 if(syn == 28) 39 { 40 oneword = scaner(); 41 syn = oneword->typenum; 42 printf("%s %d\n",oneword->word,syn); 43 } 44 else{ 45 printf("右括号错误\n"); 46 kk = 1; 47 } 48 } 49 else 50 { 51 printf("表达式错误\n"); 52 kk = 1; 53 } 54 return; 55 } 56 void term() 57 { 58 factor(); 59 while(syn == 15 || syn == 16) 60 { 61 oneword = scaner(); 62 syn = oneword->typenum; 63 printf("%s %d\n",oneword->word,syn); 64 factor(); 65 } 66 return; 67 } 68 void expression() 69 { 70 term(); 71 while(syn == 13 || syn == 14) 72 { 73 oneword = scaner(); 74 syn = oneword->typenum; 75 printf("%s %d\n",oneword->word,syn); 76 term(); 77 } 78 return; 79 } 80 void statement() 81 { 82 if(syn == 10) 83 { 84 oneword = scaner(); 85 syn = oneword->typenum; 86 printf("%s %d\n",oneword->word,syn); 87 if(syn == 18) 88 { 89 oneword = scaner(); 90 syn = oneword->typenum; 91 printf("%s %d\n",oneword->word,syn); 92 expression(); 93 } 94 else{ 95 printf("赋值号错误\n"); 96 kk = 1; 97 } 98 } 99 else{ 100 printf("语句错误\n"); 101 kk = 1; 102 } 103 return; 104 } 105 void yucu() 106 { 107 statement(); 108 while(syn == 26) 109 { 110 oneword = scaner(); 111 syn = oneword->typenum; 112 printf("%s %d\n",oneword->word,syn); 113 statement(); 114 } 115 return; 116 } 117 void Irparser() 118 { 119 if(syn == 1) 120 { 121 oneword = scaner(); 122 syn = oneword->typenum; 123 printf("%s %d\n",oneword->word,syn); 124 yucu(); 125 126 if(syn==6) 127 { 128 oneword = scaner(); 129 syn = oneword->typenum; 130 if(syn == 0 && (kk == 0)) 131 printf("success\n"); 132 } 133 else{ 134 if(kk != 1) 135 { 136 printf("缺少end错误\n"); 137 kk = 1; 138 } 139 } 140 } 141 else{ 142 printf("begin错误\n"); 143 kk = 1; 144 } 145 return; 146 } 147 int main() 148 { 149 int over = 1; 150 151 printf("Enter Your words(end with #):"); 152 scanf("%[^#]s",input); 153 p_input = 0; 154 printf("Your words:\n%s\n",input); 155 156 //获取下一个单词符号 157 oneword = scaner(); 158 syn = oneword->typenum; 159 Irparser(); 160 161 printf("\npress # to exit:"); 162 scanf("%[^#]s",input); 163 return 0; 164 } 165 char m_getch() 166 { 167 ch = input[p_input]; 168 p_input = p_input+1; 169 return(ch); 170 } 171 void getbc() 172 { 173 while(ch == ' '||ch == 10) 174 { 175 ch = input[p_input]; 176 p_input++; 177 } 178 } 179 void concat() 180 { 181 token[p_token] = ch; 182 p_token++; 183 token[p_token] = '\0'; 184 } 185 int letter() 186 { 187 if((ch >= 'a'&& ch <= 'z')|| (ch >='A'&&ch <= 'Z')) 188 return 1; 189 else 190 return 0; 191 } 192 int digit() 193 { 194 if(ch >= '0'&&ch <='9')return 1; 195 else return 0; 196 } 197 int reserve() 198 { 199 int i = 0; 200 while(strcmp(rwtab[i],_KEY_WORD_END)) 201 { 202 if(!strcmp(rwtab[i],token)) 203 return i+1; 204 i++; 205 } 206 return 10; 207 } 208 void retract() 209 { 210 p_input--; 211 } 212 213 char* dtb() 214 { 215 return NULL; 216 } 217 218 WORD* scaner() 219 { 220 221 WORD* myword = new WORD; 222 myword->typenum = 10; 223 myword->word = ""; 224 p_token = 0; 225 m_getch(); 226 getbc(); 227 if(letter()) 228 { 229 while(letter()||digit()) 230 { 231 concat(); 232 m_getch(); 233 } 234 retract(); 235 myword->typenum = reserve(); 236 myword->word = token; 237 return(myword); 238 } 239 else if(digit()) 240 { 241 while(digit()) 242 { 243 concat(); 244 m_getch(); 245 } 246 retract(); 247 myword->typenum = 11; 248 myword->word = token; 249 return(myword); 250 } 251 else switch(ch) 252 { 253 case'=':m_getch(); 254 if(ch == '=') 255 { 256 myword->typenum = 25; 257 myword->word = "=="; 258 return(myword); 259 } 260 retract(); 261 myword->typenum = 21; 262 myword->word = "="; 263 return(myword); 264 break; 265 case'+': 266 myword->typenum = 13; 267 myword->word = "+"; 268 return(myword); 269 break; 270 case'-': 271 myword->typenum = 14; 272 myword->word = "-"; 273 return(myword); 274 break; 275 case'*': 276 myword->typenum = 15; 277 myword->word = "*"; 278 return(myword); 279 break; 280 case'/': 281 myword->typenum = 16; 282 myword->word = "/"; 283 return(myword); 284 break; 285 case'(': 286 myword->typenum = 27; 287 myword->word = "("; 288 return(myword); 289 break; 290 case')': 291 myword->typenum = 28; 292 myword->word = ")"; 293 return(myword); 294 break; 295 case'[': 296 myword->typenum = 28; 297 myword->word = "["; 298 return(myword); 299 break; 300 case']': 301 myword->typenum = 29; 302 myword->word = "]"; 303 return(myword); 304 break; 305 case'{': 306 myword->typenum = 30; 307 myword->word = "{"; 308 return(myword); 309 break; 310 case'}': 311 myword->typenum = 31; 312 myword->word = "}"; 313 return(myword); 314 break; 315 case',': 316 myword->typenum = 32; 317 myword->word = ","; 318 return(myword); 319 break; 320 case':':m_getch(); 321 if(ch == '=') 322 { 323 myword->typenum = 18; 324 myword->word = ":="; 325 return(myword); 326 } 327 retract(); 328 myword->typenum = 17; 329 myword->word = ":"; 330 return(myword); 331 break; 332 case';': 333 myword->typenum = 26; 334 myword->word = ";"; 335 return(myword); 336 break; 337 case'>':m_getch(); 338 if(ch == '=') 339 { 340 myword->typenum = 24; 341 myword->word = ">="; 342 return(myword); 343 } 344 retract(); 345 myword->typenum = 23; 346 myword->word = ">"; 347 return(myword); 348 break; 349 case'<':m_getch(); 350 if(ch == '=') 351 { 352 myword->typenum = 22; 353 myword->word = "<="; 354 return(myword); 355 } 356 else if(ch == '>') 357 { 358 myword->typenum = 21; 359 myword->word = "<>"; 360 return(myword); 361 } 362 retract(); 363 myword->typenum = 20; 364 myword->word = "<"; 365 return(myword); 366 break; 367 case'!':m_getch(); 368 if(ch == '=') 369 { 370 myword->typenum = 40; 371 myword->word = "!="; 372 return(myword); 373 } 374 retract(); 375 myword->typenum = -1; 376 myword->word = "ERROR"; 377 return(myword); 378 break; 379 case'#': 380 myword->typenum = 0; 381 myword->word = "#"; 382 return(myword); 383 break; 384 case'\0': 385 myword->typenum = 0; 386 myword->word = "OVER"; 387 return(myword); 388 break; 389 default: myword->typenum = -1; 390 myword->word = "ERROR"; 391 return(myword); 392 } 393 }