1
1
#include "lex.h"
2
2
#include <stdio.h>
3
+ #include <string.h>
3
4
#include <stdlib.h>
4
5
5
6
static const char * src ;
6
7
static int * symbols ;
7
8
8
- // fields of identifier
9
+ // 标识符的描述信息
9
10
enum {Token , Hash , Name , Type , Class , Value , BType , BClass , BValue , IdSize };
10
11
11
- // types of variable/function
12
+ // 变量或者函数类型
12
13
enum { CHAR , INT , PTR };
13
14
14
- // type of declaration.
15
+ //声明类型
15
16
enum {Global , Local , Extern };
16
17
17
18
@@ -39,71 +40,94 @@ void next() {
39
40
}
40
41
41
42
else if (token == '#' ) {
42
- // skip macro, because we will not support it
43
+ //跳过宏定义,因为不支持
43
44
while (* src != 0 && * src != '\n' ) {
44
45
src ++ ;
45
46
}
46
47
}
47
48
48
-
49
49
//解析标识符
50
- else if ((token >= 'a' && token <= 'z' ) || ( token >= 'A' && token <= 'Z' ) || ( token == '_' )) {
50
+ else if (is_valid_starting_character (token )) {
51
51
52
- // parse identifier
53
52
last_pos = (char * )src - 1 ;
54
53
hash = token ;
55
54
56
55
char block_keyword [32 ];
57
- while ((* src >= 'a' && * src <= 'z' ) || ( * src >= 'A' && * src <= 'Z' ) || ( * src >= '0' && * src <= '9' ) || ( * src == '_' )) {
56
+ while (is_valid_identifier_character (* src )) {
58
57
hash = hash * 147 + * src ;
59
58
src ++ ;
60
59
}
61
60
62
-
63
- // look for existing identifier, linear search
64
61
// 搜索符号表
65
62
// 这里默认设置的IdSize即标识符的长度是10,如果两个符号的前面10个是
66
63
// 相同的,那么就区分不出来了,可以根据实际情况下重新设置其大小
67
64
current_id = symbols ;
65
+ int id_len = src - last_pos ;
68
66
while (current_id [Token ]) {
69
- if (current_id [Hash ] == hash && !memcmp ((char * )current_id [Name ], last_pos , src - last_pos )) {
70
- //found one, return
71
- //printf("find token %d\n", current_id[Token]);
67
+ if (current_id [Hash ] == hash &&
68
+ !memcmp ((char * )current_id [Name ], last_pos , id_len )) {
72
69
token = current_id [Token ];
70
+
73
71
return ;
74
72
}
75
73
//查找下一个条目
76
74
current_id = current_id + IdSize ;
77
75
}
78
76
79
- // store new ID
77
+ //如果没有找到就在新的symbols表项中创建一个ID条目
80
78
current_id [Name ] = (int )last_pos ;
81
79
current_id [Hash ] = hash ;
82
80
token = current_id [Token ] = Id ;
81
+
83
82
return ;
84
83
}
85
84
86
- //TODO 增加浮点字面量,也就是意味着要
87
85
//如果是字面量的话就计算其数值
88
86
else if (token >= '0' && token <= '9' ) {
89
- // parse number, three kinds: dec(123) hex(0x123) oct(017)
87
+ //保存浮点数字面量,之后用转换函数进行转换
88
+ char float_string [32 ];
89
+ const char * string_begin = src - 1 ;
90
+
90
91
token_val = token - '0' ;
91
92
if (token_val > 0 ) {
92
- // dec, starts with [1-9]
93
+ float_string [0 ] = token ;
94
+ int idx = 1 ;
95
+ // 十进制
93
96
while (* src >= '0' && * src <= '9' ) {
94
97
token_val = token_val * 10 + * src ++ - '0' ;
95
98
}
99
+
100
+ //检测是否可能是浮点
101
+ if (* src == '.' ){
102
+ memcpy (& float_string [1 ], string_begin , src - string_begin );
103
+ idx = idx + src - string_begin ;
104
+ float_string [idx ] = '.' ;
105
+ process_fraction (float_string , idx + 1 );
106
+ token_val = (int )strtod (float_string , NULL );
107
+ }
108
+
96
109
} else {
97
- // starts with number 0
110
+ // '0'开头的数,八进制或者十六进制或者是小数
98
111
if (* src == 'x' || * src == 'X' ) {
99
- //hex
112
+ // 十六进制
100
113
token = * ++ src ;
101
- while ((token >= '0' && token <= '9' ) || (token >= 'a' && token <= 'f' ) || (token >= 'A' && token <= 'F' )) {
102
- token_val = token_val * 16 + (token & 15 ) + (token >= 'A' ? 9 : 0 );
114
+ while ((token >= '0' && token <= '9' ) ||
115
+ (token >= 'a' && token <= 'f' ) ||
116
+ (token >= 'A' && token <= 'F' )) {
117
+ token_val = token_val * 16 + (token & 15 ) + (token >= 'A' ? 9 : 0 );
103
118
token = * ++ src ;
104
119
}
105
- } else {
106
- // oct
120
+ //TODO 增加浮点运算
121
+ }else if (* src == '.' ){
122
+ // 小数0.xxxx
123
+ float_string [0 ] = '0' ;
124
+ float_string [1 ] = '.' ;
125
+
126
+ process_fraction (float_string , 2 );
127
+
128
+ token_val = (int )strtod (float_string , NULL );
129
+ }else {
130
+ // 八进制
107
131
while (* src >= '0' && * src <= '7' ) {
108
132
token_val = token_val * 8 + * src ++ - '0' ;
109
133
}
@@ -114,15 +138,13 @@ void next() {
114
138
return ;
115
139
}
116
140
117
-
118
141
else if (token == '/' ) {
119
142
if (* src == '/' ) {
120
- // skip comments
143
+ //跳过注释
121
144
while (* src != 0 && * src != '\n' ) {
122
145
++ src ;
123
146
}
124
- } else {
125
- // divide operator
147
+ } else {
126
148
token = Div ;
127
149
return ;
128
150
}
@@ -158,7 +180,7 @@ void next() {
158
180
return ;
159
181
}
160
182
else if (token == '=' ) {
161
- // parse '==' and '='
183
+ // 解析 '==' 和 '='
162
184
if (* src == '=' ) {
163
185
src ++ ;
164
186
token = Eq ;
@@ -168,7 +190,7 @@ void next() {
168
190
return ;
169
191
}
170
192
else if (token == '+' ) {
171
- // parse '+' and '++'
193
+ // 解析 '+' 和 '++'
172
194
if (* src == '+' ) {
173
195
src ++ ;
174
196
token = Inc ;
@@ -178,7 +200,7 @@ void next() {
178
200
return ;
179
201
}
180
202
else if (token == '-' ) {
181
- // parse '-' and '--'
203
+ // 解析 '-' 和 '--'
182
204
if (* src == '-' ) {
183
205
src ++ ;
184
206
token = Dec ;
@@ -188,15 +210,15 @@ void next() {
188
210
return ;
189
211
}
190
212
else if (token == '!' ) {
191
- // parse '!='
213
+ // 解析 '!='
192
214
if (* src == '=' ) {
193
215
src ++ ;
194
216
token = Ne ;
195
217
}
196
218
return ;
197
219
}
198
220
else if (token == '<' ) {
199
- // parse '<=', '<<' or '<'
221
+ // 解析 '<=', '<<' or '<'
200
222
if (* src == '=' ) {
201
223
src ++ ;
202
224
token = Le ;
@@ -209,7 +231,7 @@ void next() {
209
231
return ;
210
232
}
211
233
else if (token == '>' ) {
212
- // parse '>=', '>>' or '>'
234
+ //解析 '>=', '>>' 或者 '>'
213
235
if (* src == '=' ) {
214
236
src ++ ;
215
237
token = Ge ;
@@ -222,7 +244,7 @@ void next() {
222
244
return ;
223
245
}
224
246
else if (token == '|' ) {
225
- // parse '|' or '||'
247
+ //解析 '|'和 '||'
226
248
if (* src == '|' ) {
227
249
src ++ ;
228
250
token = Lor ;
@@ -232,7 +254,7 @@ void next() {
232
254
return ;
233
255
}
234
256
else if (token == '&' ) {
235
- // parse '&' and '&&'
257
+ //解析 '&'和 '&&'
236
258
if (* src == '&' ) {
237
259
src ++ ;
238
260
token = Lan ;
@@ -261,7 +283,15 @@ void next() {
261
283
token = Cond ;
262
284
return ;
263
285
}
264
- else if (token == '~' || token == ';' || token == '{' || token == '}' || token == '(' || token == ')' || token == ']' || token == ',' || token == ':' ) {
286
+ else if (token == '~' ||
287
+ token == ';' ||
288
+ token == '{' ||
289
+ token == '}' ||
290
+ token == '(' ||
291
+ token == ')' ||
292
+ token == ']' ||
293
+ token == ',' ||
294
+ token == ':' ) {
265
295
// directly return the character as token;
266
296
return ;
267
297
}
@@ -277,3 +307,59 @@ void match(int tk) {
277
307
exit (-1 );
278
308
}
279
309
}
310
+
311
+ static Boolean is_valid_starting_character (char ch )
312
+ {
313
+
314
+ if ( (ch >= 'a' && ch <= 'z' ) ||
315
+ (ch >= 'A' && ch <= 'Z' ) ||
316
+ (ch == '_' )){
317
+ return True ;
318
+ }
319
+
320
+ return False ;
321
+ }
322
+
323
+
324
+ static Boolean is_valid_identifier_character (char ch )
325
+ {
326
+
327
+ if (is_valid_starting_character (ch ) || is_digit (ch )){
328
+ return True ;
329
+ }
330
+
331
+ return False ;
332
+ }
333
+
334
+ static Boolean is_digit (char ch )
335
+ {
336
+ return (ch >= '0' && ch <= '9' ) ? True : False ;
337
+ }
338
+
339
+
340
+ static void process_fraction (char * float_string , int start_idx )
341
+ {
342
+ int idx = start_idx ;
343
+
344
+ token = * ++ src ;
345
+ while ((token >= '0' && token <= '9' )){
346
+ float_string [idx ] = token ;
347
+ idx ++ ;
348
+ token = * ++ src ;
349
+ }
350
+
351
+ //判断是否是非法的浮点数字面量
352
+ printf ("trailing charater of float literal '%c'\n" , token );
353
+ if (! (token == ',' || token == ';' || token == ' ' )){
354
+ printf ("bad float literal\n" );
355
+ exit (-1 );
356
+ }
357
+
358
+ float_string [idx ] = '\0' ;
359
+ printf ("float val:%lf\n" , strtod (float_string , NULL ));
360
+
361
+
362
+ }
363
+
364
+
365
+
0 commit comments