1 #include <stdio.h>
2 #include "symbol_table_def.h"
3 //前面的那个词法和文法说明只是大概的说明,现在又有了改动,把指针运算符改为了@,把取地址运算符改为了$
4 //但是类型声明的时候的指针类型仍然是*
5 //现在所有的符号都用了,除了让人恶心的逗号和问号
6 //现在开始定义词法单元的枚举类型
7 enum lex_type
8 {
9 name,//代表字符串,包括所有的关键字和变量声明
10 delimit,//代表分号,以及大括号
11 char_type,//代表字符
12 an_operator,//代表操作符
13 constant,//代表常量
14 string_phrase,//代表字符串
15 new_line//代表换行,因为在处理的时候换行是一个很重要的符号
16 };
17 enum basic_operator_type
18 {
19 array_op=9,//代表数组分量运算
20 parenthesis,//代表括号
21 p_str_sub,//代表结构体指针分量运算
22 str_sub,//代表结构体分量运算
23 not,//代表!
24 bit_rev,//代表~
25 get_adr,//代表$
26 get_mem,//代表@
27 type_cast,//代表强制类型转换
28 negative,//代表负号运算
29 get_size,//代表sizeof
30 multi,//代表乘法
31 div,//代表除法
32 module,//代表模
33 add,//代表加法
34 minus,//代表减法
35 left_shift,//左移
36 right_shift,//右移
37 larger,//大于
38 smaller,//小于
39 lar_eqa,//大于等于
40 sma_eqa,//小于等于
41 equal,//等于
42 nequal,//不等于
43 bit_and,//&
44 bit_xor,//^
45 bit_or,//|
46 and,//&&
47 or// ||
48 };
49
50 struct first_lex_token
51 {
52 enum lex_type current_lex_type;//在第一遍处理的时候我们把所有的词素分为前面所说的六种
53 char* token_name;
54 };
55 struct first_token_chain//这个链表将所有的词法单元串联起来
56 {
57 struct first_lex_token* current_first_token;
58 struct first_token_chain* next;
59 };
60 struct first_token_chain* first_chain_head=NULL;//这里是所有节点的头节点
61 struct first_token_chain* first_chain_tail=NULL;//这里是所有节点的末尾节点,为了插入用.
62 //在第一趟处理的时候我们开两个2000个字节的缓冲区,用来读文件,并不断的切换
63 //为了表明文件的结束,我们找来了我们的老朋友 '17' ,我们用这个字符来表示缓冲区的文件末尾
64 char end_of_file=17;
65 char* buff_zone[2];//这个代表两个缓冲区
66 int buffer_pointer;//这个代表在缓冲区内的偏移
67 int file_read_byte;//这个代表在读取文件到缓冲区的时候,读取了多少个字符
68 int buff_zone_index;//代表使用的是那一个缓冲区
69 char* current_buff;//这个代表当前的缓冲区
70 int seek_begin(void )
71 {
72 //吃掉所有的空格和制表符
73 while(buffer_pointer<2000)
74 {
75 switch(*(buffer_zone[buffer_zone_index]+buffer_pointer))
76 {
77 case 17:
78 return -1;//直接返回,文件已经处理完毕了
79 break;
80 case ' ':
81 buffer_pointer++;
82 break;
83 case '\t':
84 buffer_pointer++;
85 break;
86 default:
87 break;
88 }
89 }
90 if(buffer_pointer==2000)//越过缓冲区了
91 {
92 buffer_zone_index=1-buffer_zone_index;//切换缓冲区
93 current_buff=buff_zone[buff_zone_index];
94 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
95 if(file_read_byte!=2000)//如果碰到文件的结束了
96 {
97 *(current_buff+file_read_byte)=17;//标记为文件末尾
98 //因为我们遇到的是字符文件,所以不会出现17这个字符
99 }
100 buffer_pointer=0;
101 //重新开始读取输入,这里我们默认制表符和空格符不会占用整个缓冲
102 //吃掉所有的空格和制表符
103 while(buffer_pointer<2000)
104 {
105 switch(buffer_zone[buffer_zone_index]+buffer_pointer)
106 {
107 case 17:
108 return -1;//直接返回,文件已经处理完毕了
109 break;
110 case ' ':
111 buffer_pointer++;
112 break;
113 case '\t':
114 buffer_pointer++;
115 break;
116 default:
117 break;
118 }
119 }
120 }
121
122 return 1;//代表正常的返回
123 }
124 int lex_char_type(char current)//返回当前字符的前缀集
125 {
126 char test;
127 test=current;
128 if((test>='a'&&test<='z')||(test>='A'&&test<='Z')||(test=='_'))
129 {
130 return 1;//代表名字
131 }
132 else
133 {
134 if(test>='0'&&test<='9')
135 {
136 return 2;//数字
137 }
138 else
139 {
140 if(test==';'||test=='{'||test=='}')
141 {
142 return 3;//代表分隔符
143 }
144 else
145 {
146 if(test=='\'')
147 {
148 return 4;//代表字符
149 }
150 else
151 {
152 if(test=='\"')
153 {
154 return 5;//代表字符串
155 }
156 else
157 {
158 return 6;//代表运算符
159 }
160 }
161 }
162 }
163 }
164 }
165
166
167
168 void first_procedure(FILE* input_file_name)
169 {
170 char* temp_name;//代表词法单元的内容
171 int token_length;//代表读取的词法单元的长度
172 int lex_mode;//代表开始字符所处的token种类
173 int seek_return;
174 char current_char;
175 int for_i,for_j;
176 struct first_lex_token* temp_token;
177 struct first_token_chain token_chain_node;
178 current_buff=malloc(sizeof(char)*4000);
179 buff_zone[0]=current_buff;
180 buff_zone[1]=current_buff+2000;
181 //这里我们其实上把一个4000的缓冲区分裂为两个缓冲区了,这样可以让这两个缓冲区的空间连续
182 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
183 if(file_read_byte!=2000)//如果碰到文件的结束了
184 {
185 *(current_buff+file_read_byte)=17;//标记为文件末尾
186 //因为我们遇到的是字符文件,所以不会出现17这个字符
187 }
188 buff_zone_index=0;//首先使用第一个缓冲区
189 buffer_pointer=0;
190 seek_return=seek_begin();
191 while(seek_return!=-1)//只要还没有到达末尾
192 {
193 current_char=*(buff_zone[buff_zone_index]+buffer_pointer);
194 lex_mode=lex_char_type(current_char);
195 switch(lex_mode)
196 {
197 case 1://代表名字
198 token_length=0;
199 while((current_char>='a'&¤t_char<='z')||(current_char>='A'&¤t_char<='Z')||current_char=='_')
200 {
201 token_length++;
202 buffer_pointer++;
203 if(buffer_pointer==2000)
204 {
205 buff_zone_index=1-buff_zone_index;
206 current_buff=buff_zone[buff_zone_index];
207 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
208 if(file_read_byte!=2000)//如果碰到文件的结束了
209 {
210 *(current_buff+file_read_byte)=17;//标记为文件末尾
211 //因为我们遇到的是字符文件,所以不会出现17这个字符
212 }
213 buffer_pointer=0;
214 }
215 current_char=current_buff[buffer_pointer];
216 }
217 temp_name=malloc(sizeof(char)*(token_length+1));
218 if(token_length<=buffer_pointer)
219 {
220 for(for_i=0;for_i<token_length;for_i++)
221 {
222 temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
223 }
224 }
225 else
226 {
227 current_buff=buff_zone[1-buff_zone_index];
228 for_j=token_length-buffer_pointer;
229 for(for_i=0;for_i<for_j;for_i++)
230 {
231 temp_name[for_i]=current_buff[2000-for_j+for_i];
232 }
233 current_buff=buff_zone[buff_zone_index];
234 for(for_i=0;for_i<buffer_pointer;for_i++)
235 {
236 temp_name[for_j+for_i]=current_buff[for_i];
237 }
238 }
239 temp_name[token_length]='\0';
240 temp_token=malloc(sizeof(struct first_lex_token));
241 temp_token->token_name=temp_name;
242 if(strcmp("sizeof",temp_name)==0)
243 {
244 temp_token->current_lex_type=an_operator;
245 }
246 else
247 {
248 temp_token->current_lex_type=name;
249 }
250 break;
251 case 2://对应数字常量的情况
252 token_length=0;
253 while((current_char>='0'&¤t_char<='9')||(current_char>='A'&¤t_char<='F')||\
254 (current_char>='a'&¤t_char<='f')||current_char=='x'||current_char=='X'||current_char=='.')
255 {
256 token_length++;
257 buffer_pointer++;
258 if(buffer_pointer==2000)
259 {
260 buff_zone_index=1-buff_zone_index;
261 current_buff=buff_zone[buff_zone_index];
262 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
263 if(file_read_byte!=2000)//如果碰到文件的结束了
264 {
265 *(current_buff+file_read_byte)=17;//标记为文件末尾
266 //因为我们遇到的是字符文件,所以不会出现17这个字符
267 }
268 buffer_pointer=0;
269 }
270 current_char=current_buff[buffer_pointer];
271 }
272 temp_name=malloc(sizeof(char)*(token_length+1));
273 if(token_length<=buffer_pointer)
274 {
275 for(for_i=0;for_i<token_length;for_i++)
276 {
277 temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
278 }
279 }
280 else
281 {
282 current_buff=buff_zone[1-buff_zone_index];
283 for_j=token_length-buffer_pointer;
284 for(for_i=0;for_i<for_j;for_i++)
285 {
286 temp_name[for_i]=current_buff[2000-for_j+for_i];
287 }
288 current_buff=buff_zone[buff_zone_index];
289 for(for_i=0;for_i<buffer_pointer;for_i++)
290 {
291 temp_name[for_j+for_i]=current_buff[for_i];
292 }
293 }
294 temp_name[token_length]='\0';
295 temp_token=malloc(sizeof(struct first_lex_token));
296 temp_token->token_name=temp_name;
297 temp_token->current_lex_type=constant;
298 break;
299 case 3://对应分隔符
300 temp_name=malloc(sizeof(char)*2);
301 temp_name[0]=current_buff[buffer_pointer];
302 temp_name[1]='\0';
303 buffer_pointer++;
304 if(buffer_pointer==2000)
305 {
306 buff_zone_index=1-buff_zone_index;
307 current_buff=buff_zone[buff_zone_index];
308 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
309 if(file_read_byte!=2000)//如果碰到文件的结束了
310 {
311 *(current_buff+file_read_byte)=17;//标记为文件末尾
312 //因为我们遇到的是字符文件,所以不会出现17这个字符
313 }
314 buffer_pointer=0;
315 }
316 current_char=current_buff[buffer_pointer];
317 temp_token=malloc(sizeof(struct first_lex_token));
318 temp_token->token_name=temp_name;
319 temp_token->current_lex_type=delimit;
320 break;
321 case 4://对应字符
322 token_length=0;
323 buffer_pointer++;
324 if(buffer_pointer==2000)
325 {
326 buff_zone_index=1-buff_zone_index;
327 current_buff=buff_zone[buff_zone_index];
328 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
329 if(file_read_byte!=2000)//如果碰到文件的结束了
330 {
331 *(current_buff+file_read_byte)=17;//标记为文件末尾
332 //因为我们遇到的是字符文件,所以不会出现17这个字符
333 }
334 buffer_pointer=0;
335 }
336 current_char=current_buff[buffer_pointer];
337 while(current_char!='\'')
338 {
339 token_length++;
340 buffer_pointer++;
341 if(buffer_pointer==2000)
342 {
343 buff_zone_index=1-buff_zone_index;
344 current_buff=buff_zone[buff_zone_index];
345 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
346 if(file_read_byte!=2000)//如果碰到文件的结束了
347 {
348 *(current_buff+file_read_byte)=17;//标记为文件末尾
349 //因为我们遇到的是字符文件,所以不会出现17这个字符
350 }
351 buffer_pointer=0;
352 }
353 current_char=current_buff[buffer_pointer];
354 }
355 temp_name=malloc(sizeof(char)*(token_length));
356 if(token_length<=buffer_pointer)
357 {
358 for(for_i=0;for_i<token_length;for_i++)
359 {
360 temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
361 }
362 }
363 else
364 {
365 current_buff=buff_zone[1-buff_zone_index];
366 for_j=token_length-buffer_pointer;
367 for(for_i=0;for_i<for_j;for_i++)
368 {
369 temp_name[for_i]=current_buff[2000-for_j+for_i];
370 }
371 current_buff=buff_zone[buff_zone_index];
372 for(for_i=0;for_i<buffer_pointer;for_i++)
373 {
374 temp_name[for_j+for_i]=current_buff[for_i];
375 }
376 }
377 buffer_pointer++;
378 if(buffer_pointer==2000)
379 {
380 buff_zone_index=1-buff_zone_index;
381 current_buff=buff_zone[buff_zone_index];
382 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
383 if(file_read_byte!=2000)//如果碰到文件的结束了
384 {
385 *(current_buff+file_read_byte)=17;//标记为文件末尾
386 //因为我们遇到的是字符文件,所以不会出现17这个字符
387 }
388 buffer_pointer=0;
389 }
390 temp_name[token_length-1]='\0';
391 if(temp_name[0]=='\\')//处理转义字符
392 {
393 switch(temp_name[1])
394 {
395 case 'n':
396 temp_name[0]='\n';
397 temp_name[1]='\0';
398 break;
399 case 't':
400 temp_name[0]='\t';
401 temp_name[1]='\0';
402 break;
403 case '0':
404 temp_name[0]='\0';
405 break;
406 case '\\':
407 temp_name[1]='\0';
408 break;
409 case '\'':
410 temp_name[0]='\'';
411 temp_name[1]='\0';
412 break;
413 case '\"':
414 temp_name[0]='\"';
415 temp_name[1]='\0';
416 break;
417 default:
418 break;
419 }
420 }
421 temp_token=malloc(sizeof(struct first_lex_token));
422 temp_token->token_name=temp_name;
423 temp_token->current_lex_type=constant;
424 break;
425 case 5://代表字符串
426 token_length=0;
427 buffer_pointer++;
428 if(buffer_pointer==2000)
429 {
430 buff_zone_index=1-buff_zone_index;
431 current_buff=buff_zone[buff_zone_index];
432 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
433 if(file_read_byte!=2000)//如果碰到文件的结束了
434 {
435 *(current_buff+file_read_byte)=17;//标记为文件末尾
436 //因为我们遇到的是字符文件,所以不会出现17这个字符
437 }
438 buffer_pointer=0;
439 }
440 current_char=current_buff[buffer_pointer];
441 while(1)
442 {
443 while(current_char!='\"')
444 {
445 token_length++;
446 buffer_pointer++;
447 if(buffer_pointer==2000)
448 {
449 buff_zone_index=1-buff_zone_index;
450 current_buff=buff_zone[buff_zone_index];
451 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
452 if(file_read_byte!=2000)//如果碰到文件的结束了
453 {
454 *(current_buff+file_read_byte)=17;//标记为文件末尾
455 //因为我们遇到的是字符文件,所以不会出现17这个字符
456 }
457 buffer_pointer=0;
458 }
459 current_char=current_buff[buffer_pointer];
460 }
461 if(buffer_pointer==0)//判断是否是字符串的结尾
462 {
463 if(*(buff_zone[1-buff_zone_index]+1999)!='\\')
464 {
465 break;
466 }
467 else
468 {
469 token_length++;
470 buffer_pointer++;
471 //继续下次循环
472 }
473 }
474 else
475 {
476 if(current_buff[buffer_pointer-1]!='\\')
477 {
478 break;
479 }
480 else
481 {
482 token_length++;
483 buffer_pointer++;
484 if(buffer_pointer==2000)
485 {
486 buff_zone_index=1-buff_zone_index;
487 current_buff=buff_zone[buff_zone_index];
488 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
489 if(file_read_byte!=2000)//如果碰到文件的结束了
490 {
491 *(current_buff+file_read_byte)=17;//标记为文件末尾
492 //因为我们遇到的是字符文件,所以不会出现17这个字符
493 }
494 buffer_pointer=0;
495 }
496 current_char=current_buff[buffer_pointer];
497 }
498 }
499
500
501
502 }
503 temp_name=malloc(sizeof(char)*(token_length+1));
504 if(token_length<=buffer_pointer)
505 {
506 for(for_i=0;for_i<token_length;for_i++)
507 {
508 temp_name[for_i]=current_buff[buffer_pointer-token_length+for_i];
509 }
510 }
511 else
512 {
513 current_buff=buff_zone[1-buff_zone_index];
514 for_j=token_length-buffer_pointer;
515 for(for_i=0;for_i<for_j;for_i++)
516 {
517 temp_name[for_i]=current_buff[2000-for_j+for_i];
518 }
519 current_buff=buff_zone[buff_zone_index];
520 for(for_i=0;for_i<buffer_pointer;for_i++)
521 {
522 temp_name[for_j+for_i]=current_buff[for_i];
523 }
524 }
525 temp_name[token_length]='\0';
526 buffer_pointer++;
527 temp_token=malloc(sizeof(struct first_lex_token));
528 temp_token->token_name=temp_name;
529 temp_token->current_lex_type=string_phrase;
530 break;
531 case 6://代表操作符
532 temp_name=malloc(sizeof(char)*2);
533 temp_name[0]=current_buff[buffer_pointer];
534 temp_name[1]='\0';
535 buffer_pointer++;
536 if(buffer_pointer==2000)
537 {
538 buff_zone_index=1-buff_zone_index;
539 current_buff=buff_zone[buff_zone_index];
540 file_read_byte=fread(current_buff,sizeof(char),2000,input_file_name);
541 if(file_read_byte!=2000)//如果碰到文件的结束了
542 {
543 *(current_buff+file_read_byte)=17;//标记为文件末尾
544 //因为我们遇到的是字符文件,所以不会出现17这个字符
545 }
546 buffer_pointer=0;
547 }
548 temp_token=malloc(sizeof(struct first_lex_token));
549 temp_token->token_name=temp_name;
550 temp_token->current_lex_type=an_operator;
551 break;
552 default:
553 printf(" un_recognised type\n");
554 break;
555 }
556 token_chain_node=malloc(sizeof(struct first_token_chain));
557 token_chain_node->next=NULL;
558 token_chain_node->current_first_token=temp_token;
559 if(token_chain_tail==NULL)
560 {
561 token_chain_tail=token_chain_node;
562 token_chain_head=token_chain_node;
563 }
564 else
565 {
566 token_chain_tail->next=token_chain_node;
567 token_chain_tail=token_chain_node;
568 }
569 seek_return=seek_begin();
570 }
571 }
572