OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [lex.c] - Blame information for rev 149

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
#include "c.h"
2
#include <float.h>
3
#include <errno.h>
4
 
5
static char rcsid[] = "$Id: lex.c,v 1.1 2002/08/28 23:12:44 drh Exp $";
6
 
7
#define MAXTOKEN 32
8
 
9
enum { BLANK=01,  NEWLINE=02, LETTER=04,
10
       DIGIT=010, HEX=020,    OTHER=040 };
11
 
12
static unsigned char map[256] = { /* 000 nul */ 0,
13
                                   /* 001 soh */        0,
14
                                   /* 002 stx */        0,
15
                                   /* 003 etx */        0,
16
                                   /* 004 eot */        0,
17
                                   /* 005 enq */        0,
18
                                   /* 006 ack */        0,
19
                                   /* 007 bel */        0,
20
                                   /* 010 bs  */        0,
21
                                   /* 011 ht  */        BLANK,
22
                                   /* 012 nl  */        NEWLINE,
23
                                   /* 013 vt  */        BLANK,
24
                                   /* 014 ff  */        BLANK,
25
                                   /* 015 cr  */        0,
26
                                   /* 016 so  */        0,
27
                                   /* 017 si  */        0,
28
                                   /* 020 dle */        0,
29
                                   /* 021 dc1 */        0,
30
                                   /* 022 dc2 */        0,
31
                                   /* 023 dc3 */        0,
32
                                   /* 024 dc4 */        0,
33
                                   /* 025 nak */        0,
34
                                   /* 026 syn */        0,
35
                                   /* 027 etb */        0,
36
                                   /* 030 can */        0,
37
                                   /* 031 em  */        0,
38
                                   /* 032 sub */        0,
39
                                   /* 033 esc */        0,
40
                                   /* 034 fs  */        0,
41
                                   /* 035 gs  */        0,
42
                                   /* 036 rs  */        0,
43
                                   /* 037 us  */        0,
44
                                   /* 040 sp  */        BLANK,
45
                                   /* 041 !   */        OTHER,
46
                                   /* 042 "   */        OTHER,
47
                                   /* 043 #   */        OTHER,
48
                                   /* 044 $   */        0,
49
                                   /* 045 %   */        OTHER,
50
                                   /* 046 &   */        OTHER,
51
                                   /* 047 '   */        OTHER,
52
                                   /* 050 (   */        OTHER,
53
                                   /* 051 )   */        OTHER,
54
                                   /* 052 *   */        OTHER,
55
                                   /* 053 +   */        OTHER,
56
                                   /* 054 ,   */        OTHER,
57
                                   /* 055 -   */        OTHER,
58
                                   /* 056 .   */        OTHER,
59
                                   /* 057 /   */        OTHER,
60
                                   /* 060 0   */        DIGIT,
61
                                   /* 061 1   */        DIGIT,
62
                                   /* 062 2   */        DIGIT,
63
                                   /* 063 3   */        DIGIT,
64
                                   /* 064 4   */        DIGIT,
65
                                   /* 065 5   */        DIGIT,
66
                                   /* 066 6   */        DIGIT,
67
                                   /* 067 7   */        DIGIT,
68
                                   /* 070 8   */        DIGIT,
69
                                   /* 071 9   */        DIGIT,
70
                                   /* 072 :   */        OTHER,
71
                                   /* 073 ;   */        OTHER,
72
                                   /* 074 <   */        OTHER,
73
                                   /* 075 =   */        OTHER,
74
                                   /* 076 >   */        OTHER,
75
                                   /* 077 ?   */        OTHER,
76
                                   /* 100 @   */        0,
77
                                   /* 101 A   */        LETTER|HEX,
78
                                   /* 102 B   */        LETTER|HEX,
79
                                   /* 103 C   */        LETTER|HEX,
80
                                   /* 104 D   */        LETTER|HEX,
81
                                   /* 105 E   */        LETTER|HEX,
82
                                   /* 106 F   */        LETTER|HEX,
83
                                   /* 107 G   */        LETTER,
84
                                   /* 110 H   */        LETTER,
85
                                   /* 111 I   */        LETTER,
86
                                   /* 112 J   */        LETTER,
87
                                   /* 113 K   */        LETTER,
88
                                   /* 114 L   */        LETTER,
89
                                   /* 115 M   */        LETTER,
90
                                   /* 116 N   */        LETTER,
91
                                   /* 117 O   */        LETTER,
92
                                   /* 120 P   */        LETTER,
93
                                   /* 121 Q   */        LETTER,
94
                                   /* 122 R   */        LETTER,
95
                                   /* 123 S   */        LETTER,
96
                                   /* 124 T   */        LETTER,
97
                                   /* 125 U   */        LETTER,
98
                                   /* 126 V   */        LETTER,
99
                                   /* 127 W   */        LETTER,
100
                                   /* 130 X   */        LETTER,
101
                                   /* 131 Y   */        LETTER,
102
                                   /* 132 Z   */        LETTER,
103
                                   /* 133 [   */        OTHER,
104
                                   /* 134 \   */        OTHER,
105
                                   /* 135 ]   */        OTHER,
106
                                   /* 136 ^   */        OTHER,
107
                                   /* 137 _   */        LETTER,
108
                                   /* 140 `   */        0,
109
                                   /* 141 a   */        LETTER|HEX,
110
                                   /* 142 b   */        LETTER|HEX,
111
                                   /* 143 c   */        LETTER|HEX,
112
                                   /* 144 d   */        LETTER|HEX,
113
                                   /* 145 e   */        LETTER|HEX,
114
                                   /* 146 f   */        LETTER|HEX,
115
                                   /* 147 g   */        LETTER,
116
                                   /* 150 h   */        LETTER,
117
                                   /* 151 i   */        LETTER,
118
                                   /* 152 j   */        LETTER,
119
                                   /* 153 k   */        LETTER,
120
                                   /* 154 l   */        LETTER,
121
                                   /* 155 m   */        LETTER,
122
                                   /* 156 n   */        LETTER,
123
                                   /* 157 o   */        LETTER,
124
                                   /* 160 p   */        LETTER,
125
                                   /* 161 q   */        LETTER,
126
                                   /* 162 r   */        LETTER,
127
                                   /* 163 s   */        LETTER,
128
                                   /* 164 t   */        LETTER,
129
                                   /* 165 u   */        LETTER,
130
                                   /* 166 v   */        LETTER,
131
                                   /* 167 w   */        LETTER,
132
                                   /* 170 x   */        LETTER,
133
                                   /* 171 y   */        LETTER,
134
                                   /* 172 z   */        LETTER,
135
                                   /* 173 {   */        OTHER,
136
                                   /* 174 |   */        OTHER,
137
                                   /* 175 }   */        OTHER,
138
                                   /* 176 ~   */        OTHER, };
139
static struct symbol tval;
140
static char cbuf[BUFSIZE+1];
141
static unsigned int wcbuf[BUFSIZE+1];
142
 
143
Coordinate src;         /* current source coordinate */
144
int t;
145
char *token;            /* current token */
146
Symbol tsym;            /* symbol table entry for current token */
147
 
148
static void *cput(int c, void *cl);
149
static void *wcput(int c, void *cl);
150
static void *scon(int q, void *put(int c, void *cl), void *cl);
151
static int backslash(int q);
152
static Symbol fcon(void);
153
static Symbol icon(unsigned long, int, int);
154
static void ppnumber(char *);
155
 
156
int gettok(void) {
157
        for (;;) {
158
                register unsigned char *rcp = cp;
159
                while (map[*rcp]&BLANK)
160
                        rcp++;
161
                if (limit - rcp < MAXTOKEN) {
162
                        cp = rcp;
163
                        fillbuf();
164
                        rcp = cp;
165
                }
166
                src.file = file;
167
                src.x = (char *)rcp - line;
168
                src.y = lineno;
169
                cp = rcp + 1;
170
                switch (*rcp++) {
171
                case '/': if (*rcp == '*') {
172
                                int c = 0;
173
                                for (rcp++; *rcp != '/' || c != '*'; )
174
                                        if (map[*rcp]&NEWLINE) {
175
                                                if (rcp < limit)
176
                                                        c = *rcp;
177
                                                cp = rcp + 1;
178
                                                nextline();
179
                                                rcp = cp;
180
                                                if (rcp == limit)
181
                                                        break;
182
                                        } else
183
                                                c = *rcp++;
184
                                if (rcp < limit)
185
                                        rcp++;
186
                                else
187
                                        error("unclosed comment\n");
188
                                cp = rcp;
189
                                continue;
190
                          }
191
                          return '/';
192
                case '<':
193
                        if (*rcp == '=') return cp++, LEQ;
194
                        if (*rcp == '<') return cp++, LSHIFT;
195
                        return '<';
196
                case '>':
197
                        if (*rcp == '=') return cp++, GEQ;
198
                        if (*rcp == '>') return cp++, RSHIFT;
199
                        return '>';
200
                case '-':
201
                        if (*rcp == '>') return cp++, DEREF;
202
                        if (*rcp == '-') return cp++, DECR;
203
                        return '-';
204
                case '=': return *rcp == '=' ? cp++, EQL    : '=';
205
                case '!': return *rcp == '=' ? cp++, NEQ    : '!';
206
                case '|': return *rcp == '|' ? cp++, OROR   : '|';
207
                case '&': return *rcp == '&' ? cp++, ANDAND : '&';
208
                case '+': return *rcp == '+' ? cp++, INCR   : '+';
209
                case ';': case ',': case ':':
210
                case '*': case '~': case '%': case '^': case '?':
211
                case '[': case ']': case '{': case '}': case '(': case ')':
212
                        return rcp[-1];
213
                case '\n': case '\v': case '\r': case '\f':
214
                        nextline();
215
                        if (cp == limit) {
216
                                tsym = NULL;
217
                                return EOI;
218
                        }
219
                        continue;
220
 
221
                case 'i':
222
                        if (rcp[0] == 'f'
223
                        && !(map[rcp[1]]&(DIGIT|LETTER))) {
224
                                cp = rcp + 1;
225
                                return IF;
226
                        }
227
                        if (rcp[0] == 'n'
228
                        &&  rcp[1] == 't'
229
                        && !(map[rcp[2]]&(DIGIT|LETTER))) {
230
                                cp = rcp + 2;
231
                                tsym = inttype->u.sym;
232
                                return INT;
233
                        }
234
                        goto id;
235
                case 'h': case 'j': case 'k': case 'm': case 'n': case 'o':
236
                case 'p': case 'q': case 'x': case 'y': case 'z':
237
                case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
238
                case 'G': case 'H': case 'I': case 'J': case 'K':
239
                case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
240
                case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
241
                case 'Y': case 'Z':
242
                id:
243
                        if (limit - rcp < MAXLINE) {
244
                                cp = rcp - 1;
245
                                fillbuf();
246
                                rcp = ++cp;
247
                        }
248
                        assert(cp == rcp);
249
                        token = (char *)rcp - 1;
250
                        while (map[*rcp]&(DIGIT|LETTER))
251
                                rcp++;
252
                        token = stringn(token, (char *)rcp - token);
253
                        tsym = lookup(token, identifiers);
254
                        cp = rcp;
255
                        return ID;
256
                case '0': case '1': case '2': case '3': case '4':
257
                case '5': case '6': case '7': case '8': case '9': {
258
                        unsigned long n = 0;
259
                        if (limit - rcp < MAXLINE) {
260
                                cp = rcp - 1;
261
                                fillbuf();
262
                                rcp = ++cp;
263
                        }
264
                        assert(cp == rcp);
265
                        token = (char *)rcp - 1;
266
                        if (*token == '0' && (*rcp == 'x' || *rcp == 'X')) {
267
                                int d, overflow = 0;
268
                                while (*++rcp) {
269
                                        if (map[*rcp]&DIGIT)
270
                                                d = *rcp - '0';
271
                                        else if (*rcp >= 'a' && *rcp <= 'f')
272
                                                d = *rcp - 'a' + 10;
273
                                        else if (*rcp >= 'A' && *rcp <= 'F')
274
                                                d = *rcp - 'A' + 10;
275
                                        else
276
                                                break;
277
                                        if (n&~(~0UL >> 4))
278
                                                overflow = 1;
279
                                        else
280
                                                n = (n<<4) + d;
281
                                }
282
                                if ((char *)rcp - token <= 2)
283
                                        error("invalid hexadecimal constant `%S'\n", token, (char *)rcp-token);
284
                                cp = rcp;
285
                                tsym = icon(n, overflow, 16);
286
                        } else if (*token == '0') {
287
                                int err = 0, overflow = 0;
288
                                for ( ; map[*rcp]&DIGIT; rcp++) {
289
                                        if (*rcp == '8' || *rcp == '9')
290
                                                err = 1;
291
                                        if (n&~(~0UL >> 3))
292
                                                overflow = 1;
293
                                        else
294
                                                n = (n<<3) + (*rcp - '0');
295
                                }
296
                                if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
297
                                        cp = rcp;
298
                                        tsym = fcon();
299
                                        return FCON;
300
                                }
301
                                cp = rcp;
302
                                tsym = icon(n, overflow, 8);
303
                                if (err)
304
                                        error("invalid octal constant `%S'\n", token, (char*)cp-token);
305
                        } else {
306
                                int overflow = 0;
307
                                for (n = *token - '0'; map[*rcp]&DIGIT; ) {
308
                                        int d = *rcp++ - '0';
309
                                        if (n > (ULONG_MAX - d)/10)
310
                                                overflow = 1;
311
                                        else
312
                                                n = 10*n + d;
313
                                }
314
                                if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') {
315
                                        cp = rcp;
316
                                        tsym = fcon();
317
                                        return FCON;
318
                                }
319
                                cp = rcp;
320
                                tsym = icon(n, overflow, 10);
321
                        }
322
                        return ICON;
323
                }
324
                case '.':
325
                        if (rcp[0] == '.' && rcp[1] == '.') {
326
                                cp += 2;
327
                                return ELLIPSIS;
328
                        }
329
                        if ((map[*rcp]&DIGIT) == 0)
330
                                return '.';
331
                        if (limit - rcp < MAXLINE) {
332
                                cp = rcp - 1;
333
                                fillbuf();
334
                                rcp = ++cp;
335
                        }
336
                        assert(cp == rcp);
337
                        cp = rcp - 1;
338
                        token = (char *)cp;
339
                        tsym = fcon();
340
                        return FCON;
341
                case 'L':
342
                        if (*rcp == '\'') {
343
                                unsigned int *s = scon(*cp, wcput, wcbuf);
344
                                if (s - wcbuf > 2)
345
                                        warning("excess characters in wide-character literal ignored\n");
346
                                tval.type = widechar;
347
                                tval.u.c.v.u = wcbuf[0];
348
                                tsym = &tval;
349
                                return ICON;
350
                        } else if (*rcp == '"') {
351
                                unsigned int *s = scon(*cp, wcput, wcbuf);
352
                                tval.type = array(widechar, s - wcbuf, 0);
353
                                tval.u.c.v.p = wcbuf;
354
                                tsym = &tval;
355
                                return SCON;
356
                        } else
357
                                goto id;
358
                case '\'': {
359
                        char *s = scon(*--cp, cput, cbuf);
360
                        if (s - cbuf > 2)
361
                                warning("excess characters in multibyte character literal ignored\n");
362
                        tval.type = inttype;
363
                        if (chartype->op == INT)
364
                                tval.u.c.v.i = extend(cbuf[0], chartype);
365
                        else
366
                                tval.u.c.v.i = cbuf[0]&0xFF;
367
                        tsym = &tval;
368
                        return ICON;
369
                        }
370
                case '"': {
371
                        char *s = scon(*--cp, cput, cbuf);
372
                        tval.type = array(chartype, s - cbuf, 0);
373
                        tval.u.c.v.p = cbuf;
374
                        tsym = &tval;
375
                        return SCON;
376
                        }
377
                case 'a':
378
                        if (rcp[0] == 'u'
379
                        &&  rcp[1] == 't'
380
                        &&  rcp[2] == 'o'
381
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
382
                                cp = rcp + 3;
383
                                return AUTO;
384
                        }
385
                        goto id;
386
                case 'b':
387
                        if (rcp[0] == 'r'
388
                        &&  rcp[1] == 'e'
389
                        &&  rcp[2] == 'a'
390
                        &&  rcp[3] == 'k'
391
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
392
                                cp = rcp + 4;
393
                                return BREAK;
394
                        }
395
                        goto id;
396
                case 'c':
397
                        if (rcp[0] == 'a'
398
                        &&  rcp[1] == 's'
399
                        &&  rcp[2] == 'e'
400
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
401
                                cp = rcp + 3;
402
                                return CASE;
403
                        }
404
                        if (rcp[0] == 'h'
405
                        &&  rcp[1] == 'a'
406
                        &&  rcp[2] == 'r'
407
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
408
                                cp = rcp + 3;
409
                                tsym = chartype->u.sym;
410
                                return CHAR;
411
                        }
412
                        if (rcp[0] == 'o'
413
                        &&  rcp[1] == 'n'
414
                        &&  rcp[2] == 's'
415
                        &&  rcp[3] == 't'
416
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
417
                                cp = rcp + 4;
418
                                return CONST;
419
                        }
420
                        if (rcp[0] == 'o'
421
                        &&  rcp[1] == 'n'
422
                        &&  rcp[2] == 't'
423
                        &&  rcp[3] == 'i'
424
                        &&  rcp[4] == 'n'
425
                        &&  rcp[5] == 'u'
426
                        &&  rcp[6] == 'e'
427
                        && !(map[rcp[7]]&(DIGIT|LETTER))) {
428
                                cp = rcp + 7;
429
                                return CONTINUE;
430
                        }
431
                        goto id;
432
                case 'd':
433
                        if (rcp[0] == 'e'
434
                        &&  rcp[1] == 'f'
435
                        &&  rcp[2] == 'a'
436
                        &&  rcp[3] == 'u'
437
                        &&  rcp[4] == 'l'
438
                        &&  rcp[5] == 't'
439
                        && !(map[rcp[6]]&(DIGIT|LETTER))) {
440
                                cp = rcp + 6;
441
                                return DEFAULT;
442
                        }
443
                        if (rcp[0] == 'o'
444
                        &&  rcp[1] == 'u'
445
                        &&  rcp[2] == 'b'
446
                        &&  rcp[3] == 'l'
447
                        &&  rcp[4] == 'e'
448
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
449
                                cp = rcp + 5;
450
                                tsym = doubletype->u.sym;
451
                                return DOUBLE;
452
                        }
453
                        if (rcp[0] == 'o'
454
                        && !(map[rcp[1]]&(DIGIT|LETTER))) {
455
                                cp = rcp + 1;
456
                                return DO;
457
                        }
458
                        goto id;
459
                case 'e':
460
                        if (rcp[0] == 'l'
461
                        &&  rcp[1] == 's'
462
                        &&  rcp[2] == 'e'
463
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
464
                                cp = rcp + 3;
465
                                return ELSE;
466
                        }
467
                        if (rcp[0] == 'n'
468
                        &&  rcp[1] == 'u'
469
                        &&  rcp[2] == 'm'
470
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
471
                                cp = rcp + 3;
472
                                return ENUM;
473
                        }
474
                        if (rcp[0] == 'x'
475
                        &&  rcp[1] == 't'
476
                        &&  rcp[2] == 'e'
477
                        &&  rcp[3] == 'r'
478
                        &&  rcp[4] == 'n'
479
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
480
                                cp = rcp + 5;
481
                                return EXTERN;
482
                        }
483
                        goto id;
484
                case 'f':
485
                        if (rcp[0] == 'l'
486
                        &&  rcp[1] == 'o'
487
                        &&  rcp[2] == 'a'
488
                        &&  rcp[3] == 't'
489
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
490
                                cp = rcp + 4;
491
                                tsym = floattype->u.sym;
492
                                return FLOAT;
493
                        }
494
                        if (rcp[0] == 'o'
495
                        &&  rcp[1] == 'r'
496
                        && !(map[rcp[2]]&(DIGIT|LETTER))) {
497
                                cp = rcp + 2;
498
                                return FOR;
499
                        }
500
                        goto id;
501
                case 'g':
502
                        if (rcp[0] == 'o'
503
                        &&  rcp[1] == 't'
504
                        &&  rcp[2] == 'o'
505
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
506
                                cp = rcp + 3;
507
                                return GOTO;
508
                        }
509
                        goto id;
510
                case 'l':
511
                        if (rcp[0] == 'o'
512
                        &&  rcp[1] == 'n'
513
                        &&  rcp[2] == 'g'
514
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
515
                                cp = rcp + 3;
516
                                return LONG;
517
                        }
518
                        goto id;
519
                case 'r':
520
                        if (rcp[0] == 'e'
521
                        &&  rcp[1] == 'g'
522
                        &&  rcp[2] == 'i'
523
                        &&  rcp[3] == 's'
524
                        &&  rcp[4] == 't'
525
                        &&  rcp[5] == 'e'
526
                        &&  rcp[6] == 'r'
527
                        && !(map[rcp[7]]&(DIGIT|LETTER))) {
528
                                cp = rcp + 7;
529
                                return REGISTER;
530
                        }
531
                        if (rcp[0] == 'e'
532
                        &&  rcp[1] == 't'
533
                        &&  rcp[2] == 'u'
534
                        &&  rcp[3] == 'r'
535
                        &&  rcp[4] == 'n'
536
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
537
                                cp = rcp + 5;
538
                                return RETURN;
539
                        }
540
                        goto id;
541
                case 's':
542
                        if (rcp[0] == 'h'
543
                        &&  rcp[1] == 'o'
544
                        &&  rcp[2] == 'r'
545
                        &&  rcp[3] == 't'
546
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
547
                                cp = rcp + 4;
548
                                return SHORT;
549
                        }
550
                        if (rcp[0] == 'i'
551
                        &&  rcp[1] == 'g'
552
                        &&  rcp[2] == 'n'
553
                        &&  rcp[3] == 'e'
554
                        &&  rcp[4] == 'd'
555
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
556
                                cp = rcp + 5;
557
                                return SIGNED;
558
                        }
559
                        if (rcp[0] == 'i'
560
                        &&  rcp[1] == 'z'
561
                        &&  rcp[2] == 'e'
562
                        &&  rcp[3] == 'o'
563
                        &&  rcp[4] == 'f'
564
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
565
                                cp = rcp + 5;
566
                                return SIZEOF;
567
                        }
568
                        if (rcp[0] == 't'
569
                        &&  rcp[1] == 'a'
570
                        &&  rcp[2] == 't'
571
                        &&  rcp[3] == 'i'
572
                        &&  rcp[4] == 'c'
573
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
574
                                cp = rcp + 5;
575
                                return STATIC;
576
                        }
577
                        if (rcp[0] == 't'
578
                        &&  rcp[1] == 'r'
579
                        &&  rcp[2] == 'u'
580
                        &&  rcp[3] == 'c'
581
                        &&  rcp[4] == 't'
582
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
583
                                cp = rcp + 5;
584
                                return STRUCT;
585
                        }
586
                        if (rcp[0] == 'w'
587
                        &&  rcp[1] == 'i'
588
                        &&  rcp[2] == 't'
589
                        &&  rcp[3] == 'c'
590
                        &&  rcp[4] == 'h'
591
                        && !(map[rcp[5]]&(DIGIT|LETTER))) {
592
                                cp = rcp + 5;
593
                                return SWITCH;
594
                        }
595
                        goto id;
596
                case 't':
597
                        if (rcp[0] == 'y'
598
                        &&  rcp[1] == 'p'
599
                        &&  rcp[2] == 'e'
600
                        &&  rcp[3] == 'd'
601
                        &&  rcp[4] == 'e'
602
                        &&  rcp[5] == 'f'
603
                        && !(map[rcp[6]]&(DIGIT|LETTER))) {
604
                                cp = rcp + 6;
605
                                return TYPEDEF;
606
                        }
607
                        goto id;
608
                case 'u':
609
                        if (rcp[0] == 'n'
610
                        &&  rcp[1] == 'i'
611
                        &&  rcp[2] == 'o'
612
                        &&  rcp[3] == 'n'
613
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
614
                                cp = rcp + 4;
615
                                return UNION;
616
                        }
617
                        if (rcp[0] == 'n'
618
                        &&  rcp[1] == 's'
619
                        &&  rcp[2] == 'i'
620
                        &&  rcp[3] == 'g'
621
                        &&  rcp[4] == 'n'
622
                        &&  rcp[5] == 'e'
623
                        &&  rcp[6] == 'd'
624
                        && !(map[rcp[7]]&(DIGIT|LETTER))) {
625
                                cp = rcp + 7;
626
                                return UNSIGNED;
627
                        }
628
                        goto id;
629
                case 'v':
630
                        if (rcp[0] == 'o'
631
                        &&  rcp[1] == 'i'
632
                        &&  rcp[2] == 'd'
633
                        && !(map[rcp[3]]&(DIGIT|LETTER))) {
634
                                cp = rcp + 3;
635
                                tsym = voidtype->u.sym;
636
                                return VOID;
637
                        }
638
                        if (rcp[0] == 'o'
639
                        &&  rcp[1] == 'l'
640
                        &&  rcp[2] == 'a'
641
                        &&  rcp[3] == 't'
642
                        &&  rcp[4] == 'i'
643
                        &&  rcp[5] == 'l'
644
                        &&  rcp[6] == 'e'
645
                        && !(map[rcp[7]]&(DIGIT|LETTER))) {
646
                                cp = rcp + 7;
647
                                return VOLATILE;
648
                        }
649
                        goto id;
650
                case 'w':
651
                        if (rcp[0] == 'h'
652
                        &&  rcp[1] == 'i'
653
                        &&  rcp[2] == 'l'
654
                        &&  rcp[3] == 'e'
655
                        && !(map[rcp[4]]&(DIGIT|LETTER))) {
656
                                cp = rcp + 4;
657
                                return WHILE;
658
                        }
659
                        goto id;
660
                case '_':
661
                        if (rcp[0] == '_'
662
                        &&  rcp[1] == 't'
663
                        &&  rcp[2] == 'y'
664
                        &&  rcp[3] == 'p'
665
                        &&  rcp[4] == 'e'
666
                        &&  rcp[5] == 'c'
667
                        &&  rcp[6] == 'o'
668
                        &&  rcp[7] == 'd'
669
                        &&  rcp[8] == 'e'
670
                        && !(map[rcp[9]]&(DIGIT|LETTER))) {
671
                                cp = rcp + 9;
672
                                return TYPECODE;
673
                        }
674
                        if (rcp[0] == '_'
675
                        &&  rcp[1] == 'f'
676
                        &&  rcp[2] == 'i'
677
                        &&  rcp[3] == 'r'
678
                        &&  rcp[4] == 's'
679
                        &&  rcp[5] == 't'
680
                        &&  rcp[6] == 'a'
681
                        &&  rcp[7] == 'r'
682
                        &&  rcp[8] == 'g'
683
                        && !(map[rcp[9]]&(DIGIT|LETTER))) {
684
                                cp = rcp + 9;
685
                                return FIRSTARG;
686
                        }
687
                        goto id;
688
                default:
689
                        if ((map[cp[-1]]&BLANK) == 0)
690
                                if (cp[-1] < ' ' || cp[-1] >= 0177)
691
                                        error("illegal character `\\0%o'\n", cp[-1]);
692
                                else
693
                                        error("illegal character `%c'\n", cp[-1]);
694
                }
695
        }
696
}
697
static Symbol icon(unsigned long n, int overflow, int base) {
698
        if ((*cp=='u'||*cp=='U') && (cp[1]=='l'||cp[1]=='L')
699
        ||  (*cp=='l'||*cp=='L') && (cp[1]=='u'||cp[1]=='U')) {
700
                tval.type = unsignedlong;
701
                cp += 2;
702
        } else if (*cp == 'u' || *cp == 'U') {
703
                if (overflow || n > unsignedtype->u.sym->u.limits.max.i)
704
                        tval.type = unsignedlong;
705
                else
706
                        tval.type = unsignedtype;
707
                cp += 1;
708
        } else if (*cp == 'l' || *cp == 'L') {
709
                if (overflow || n > longtype->u.sym->u.limits.max.i)
710
                        tval.type = unsignedlong;
711
                else
712
                        tval.type = longtype;
713
                cp += 1;
714
        } else if (overflow || n > longtype->u.sym->u.limits.max.i)
715
                tval.type = unsignedlong;
716
        else if (base != 10 &&
717
                        n > inttype->u.sym->u.limits.max.i &&
718
                        n <= unsignedtype->u.sym->u.limits.max.i)
719
                tval.type = unsignedtype;
720
        else if (n > inttype->u.sym->u.limits.max.i)
721
                tval.type = longtype;
722
        else
723
                tval.type = inttype;
724
        switch (tval.type->op) {
725
        case INT:
726
                if (overflow || n > tval.type->u.sym->u.limits.max.i) {
727
                        warning("overflow in constant `%S'\n", token,
728
                                (char*)cp - token);
729
                        tval.u.c.v.i = tval.type->u.sym->u.limits.max.i;
730
                } else
731
                        tval.u.c.v.i = n;
732
                break;
733
        case UNSIGNED:
734
                if (overflow || n > tval.type->u.sym->u.limits.max.u) {
735
                        warning("overflow in constant `%S'\n", token,
736
                                (char*)cp - token);
737
                        tval.u.c.v.u = tval.type->u.sym->u.limits.max.u;
738
                } else
739
                        tval.u.c.v.u = n;
740
                break;
741
        default: assert(0);
742
        }
743
        ppnumber("integer");
744
        return &tval;
745
}
746
static void ppnumber(char *which) {
747
        unsigned char *rcp = cp--;
748
 
749
        for ( ; (map[*cp]&(DIGIT|LETTER)) || *cp == '.'; cp++)
750
                if ((cp[0] == 'E' || cp[0] == 'e')
751
                &&  (cp[1] == '-' || cp[1] == '+'))
752
                        cp++;
753
        if (cp > rcp)
754
                error("`%S' is a preprocessing number but an invalid %s constant\n", token,
755
 
756
                        (char*)cp-token, which);
757
}
758
static Symbol fcon(void) {
759
        if (*cp == '.')
760
                do
761
                        cp++;
762
                while (map[*cp]&DIGIT);
763
        if (*cp == 'e' || *cp == 'E') {
764
                if (*++cp == '-' || *cp == '+')
765
                        cp++;
766
                if (map[*cp]&DIGIT)
767
                        do
768
                                cp++;
769
                        while (map[*cp]&DIGIT);
770
                else
771
                        error("invalid floating constant `%S'\n", token,
772
                                (char*)cp - token);
773
        }
774
 
775
        errno = 0;
776
        tval.u.c.v.d = strtod(token, NULL);
777
        if (errno == ERANGE)
778
                warning("overflow in floating constant `%S'\n", token,
779
                        (char*)cp - token);
780
        if (*cp == 'f' || *cp == 'F') {
781
                ++cp;
782
                if (tval.u.c.v.d > floattype->u.sym->u.limits.max.d)
783
                        warning("overflow in floating constant `%S'\n", token,
784
                                (char*)cp - token);
785
                tval.type = floattype;
786
        } else if (*cp == 'l' || *cp == 'L') {
787
                cp++;
788
                tval.type = longdouble;
789
        } else {
790
                if (tval.u.c.v.d > doubletype->u.sym->u.limits.max.d)
791
                        warning("overflow in floating constant `%S'\n", token,
792
                                (char*)cp - token);
793
                tval.type = doubletype;
794
        }
795
        ppnumber("floating");
796
        return &tval;
797
}
798
 
799
static void *cput(int c, void *cl) {
800
        char *s = cl;
801
 
802
        if (c < 0 || c > 255)
803
                warning("overflow in escape sequence with resulting value `%d'\n", c);
804
        *s++ = c;
805
        return s;
806
}
807
 
808
static void *wcput(int c, void *cl) {
809
        unsigned int *s = cl;
810
 
811
        *s++ = c;
812
        return s;
813
}
814
 
815
static void *scon(int q, void *put(int c, void *cl), void *cl) {
816
        int n = 0, nbad = 0;
817
 
818
        do {
819
                cp++;
820
                while (*cp != q) {
821
                        int c;
822
                        if (map[*cp]&NEWLINE) {
823
                                if (cp < limit)
824
                                        break;
825
                                cp++;
826
                                nextline();
827
                                if (cp == limit)
828
                                        break;
829
                                continue;
830
                        }
831
                        c = *cp++;
832
                        if (c == '\\') {
833
                                if (map[*cp]&NEWLINE) {
834
                                        if (cp++ < limit)
835
                                                continue;
836
                                        nextline();
837
                                }
838
                                if (limit - cp < MAXTOKEN)
839
                                        fillbuf();
840
                                c = backslash(q);
841
                        } else if (c < 0 || c > 255 || map[c] == 0)
842
                                nbad++;
843
                        if (n++ < BUFSIZE)
844
                                cl = put(c, cl);
845
                }
846
                if (*cp == q)
847
                        cp++;
848
                else
849
                        error("missing %c\n", q);
850
                if (q == '"' && put == wcput && getchr() == 'L') {
851
                        if (limit - cp < 2)
852
                                fillbuf();
853
                        if (cp[1] == '"')
854
                                cp++;
855
                }
856
        } while (q == '"' && getchr() == '"');
857
        cl = put(0, cl);
858
        if (n >= BUFSIZE)
859
                error("%s literal too long\n", q == '"' ? "string" : "character");
860
        if (Aflag >= 2 && q == '"' && n > 509)
861
                warning("more than 509 characters in a string literal\n");
862
        if (Aflag >= 2 && nbad > 0)
863
                warning("%s literal contains non-portable characters\n",
864
                        q == '"' ? "string" : "character");
865
        return cl;
866
}
867
int getchr(void) {
868
        for (;;) {
869
                while (map[*cp]&BLANK)
870
                        cp++;
871
                if (!(map[*cp]&NEWLINE))
872
                        return *cp;
873
                cp++;
874
                nextline();
875
                if (cp == limit)
876
                        return EOI;
877
        }
878
}
879
static int backslash(int q) {
880
        unsigned int c;
881
 
882
        switch (*cp++) {
883
        case 'a': return 7;
884
        case 'b': return '\b';
885
        case 'f': return '\f';
886
        case 'n': return '\n';
887
        case 'r': return '\r';
888
        case 't': return '\t';
889
        case 'v': return '\v';
890
        case '\'': case '"': case '\\': case '\?': break;
891
        case 'x': {
892
                int overflow = 0;
893
                if ((map[*cp]&(DIGIT|HEX)) == 0) {
894
                        if (*cp < ' ' || *cp == 0177)
895
                                error("ill-formed hexadecimal escape sequence\n");
896
                        else
897
                                error("ill-formed hexadecimal escape sequence `\\x%c'\n", *cp);
898
                        if (*cp != q)
899
                                cp++;
900
                        return 0;
901
                }
902
                for (c = 0; map[*cp]&(DIGIT|HEX); cp++) {
903
                        if (c >> (8*widechar->size - 4))
904
                                overflow = 1;
905
                        if (map[*cp]&DIGIT)
906
                                c = (c<<4) + *cp - '0';
907
                        else
908
                                c = (c<<4) + (*cp&~040) - 'A' + 10;
909
                }
910
                if (overflow)
911
                        warning("overflow in hexadecimal escape sequence\n");
912
                return c&ones(8*widechar->size);
913
                }
914
        case '0': case '1': case '2': case '3':
915
        case '4': case '5': case '6': case '7':
916
                c = *(cp-1) - '0';
917
                if (*cp >= '0' && *cp <= '7') {
918
                        c = (c<<3) + *cp++ - '0';
919
                        if (*cp >= '0' && *cp <= '7')
920
                                c = (c<<3) + *cp++ - '0';
921
                }
922
                return c;
923
        default:
924
                if (cp[-1] < ' ' || cp[-1] >= 0177)
925
                        warning("unrecognized character escape sequence\n");
926
                else
927
                        warning("unrecognized character escape sequence `\\%c'\n", cp[-1]);
928
        }
929
        return cp[-1];
930
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.