519579358f45cb5ecb6c44e288ae8da50a85e5a1
[linux-libre-firmware.git] / a56 / lex.c
1 /*******************************************************
2  *
3  *  a56 - a DSP56001 assembler
4  *
5  *  Written by Quinn C. Jensen
6  *  July 1990
7  *
8  *******************************************************\
9
10 /*
11  *  lex.c - lexical analyzer envelope.  lexyy.c, included below,
12  *  is the LEX-generated code.
13  *
14  */
15
16 #include "a56.h"
17 #include "gram.h"
18
19 int ldebug = 0;
20 #ifdef LDEBUG
21 #define RET(val) \
22         {\
23                 if(ldebug) {\
24                         printf("[%s]", tok_print(val));\
25                         fflush(stdout);\
26                 }\
27                 return val;\
28         }
29 #else
30 #define RET(val) {return val;}
31 #endif
32
33 extern YYSTYPE yyval;
34
35 double atof();
36
37 /**************** yylex - returns next token *****************************/
38
39 #define MAX_TOK 1024
40 char tok[MAX_TOK];
41
42 yylex()
43 {
44         int ltok = next_tok();
45         int itok;
46
47         switch(ltok) {
48         case EOF:
49                 if(yywrap() == 1)
50                         return 0;
51                 else
52                         return yylex();
53                 break;
54         case SYM:
55                 if(itok = is_keyword(tok)) {
56                         RET(itok);
57                 } else {
58                         yylval.sval = strsave(tok);
59                         RET(SYM);
60                 }
61                 break;
62         case CHEX:
63                 yylval.n.type = INT;
64                 yylval.n.seg = ANY;
65                 yylval.n.val.i = strtol(tok, 0, 16);
66                 RET(CHEX);
67                 break;
68         case CDEC:
69                 yylval.n.type= INT;
70                 yylval.n.seg = ANY;
71                 yylval.n.val.i = atoi(tok);
72                 RET(CDEC);
73                 break;
74         case FRAC:
75                 yylval.n.type = FLT;
76                 yylval.n.seg = ANY;
77                 yylval.n.val.f = atof(tok);
78                 RET(FRAC);
79         case CHAR:
80                 yylval.cval = *tok;
81                 RET(CHAR);
82         case STRING:
83                 yylval.sval = (char *)fixstring(tok);
84                 yylval.sval = strsave(yylval.sval);
85                 RET(STRING);
86         default:
87                 RET(ltok);
88         }
89 }
90
91 is_keyword(tok)
92 char *tok;
93 {
94         int kval = kparse(tok);
95         if(kval > 0)
96                 return kval;
97
98         return 0;
99 }
100
101 struct ascii_tab {
102         char *str;
103         int flags;
104 } ascii_tab[];
105 #define IS_NONE         0x0000
106 #define IS_NUM          0x0001
107 #define IS_ALPHA        0x0002
108 #define IS_HEX          0x0004
109 #define IS_WHITE        0x0008
110
111 extern FILE *yyin;
112
113 int next_tok()
114 {
115         char *tp = tok;
116         enum {S_TOP, S_HEXNUM, S_NUM, S_ALNUM, S_CHAR, S_ESC_CHAR, S_COMMENT,
117                 S_SQ_STRING, S_DQ_STRING, S_SHL, S_SHR} state = S_TOP;
118         static int unget = 0;
119         BOOL dot_seen = FALSE;
120
121         for(;;) {
122                 int c = unget ? unget : lgetc(yyin);
123                 int flags;
124                 unget = 0;
125                 flags = ascii_tab[c & 0x7F].flags;
126                 if(tp > tok + MAX_TOK - 2) return LEXBAD;
127                 switch(state) {
128                 case S_TOP:
129                         if(c == EOF) {
130                                 return EOF;
131                         } else if(flags & IS_WHITE) {
132                                 /* ignore */ ;
133                         } else if(flags & IS_ALPHA) {
134                                 *tp++ = c;
135                                 state = S_ALNUM;
136                         } else if((flags & IS_NUM) || c == '.') {
137                                 unget = c;
138                                 state = S_NUM;
139                         } else {
140                                 switch(c) {
141                                 case '$': state = S_HEXNUM; break;
142                                 case '"': state = S_DQ_STRING; break;
143                                 case '\'': state = S_CHAR; break;
144                                 case '>': state = S_SHR; break;
145                                 case '<': state = S_SHL; break;
146                                 case ';': state = S_COMMENT; break;
147                                 case '\n': return EOL;
148                                 case '@': return EOS;
149                                 default: return c;
150                                 }
151                         }
152                         break;
153                 case S_COMMENT:
154                         if(c == EOF) {
155                                 unget = EOF;
156                                 *tp = '\0';
157                                 return EOL;
158                         } else if(c == '\n') {
159                                 return EOL;
160                         }
161                         break;
162                 case S_SHR:
163                         if(c == EOF) {
164                                 unget = EOF;
165                                 *tp = '\0';
166                                 return '>';
167                         } else if(c == '>') {
168                                 return SHR;
169                         } else {
170                                 unget = c;
171                                 return '>';
172                         }
173                         break;
174                 case S_SHL:
175                         if(c == EOF) {
176                                 unget = EOF;
177                                 *tp = '\0';
178                                 return '<';
179                         } else if(c == '<') {
180                                 return SHL;
181                         } else {
182                                 unget = c;
183                                 return '<';
184                         }
185                         break;
186                 case S_HEXNUM:
187                         if(c == EOF) {
188                                 unget = EOF;
189                                 *tp = '\0';
190                                 return CHEX;
191                         } else if(flags & IS_HEX) {
192                                 *tp++ = c;
193                                 break;
194                         } else {
195                                 unget = c;
196                                 *tp = '\0';
197                                 return CHEX;
198                         }
199                         break;
200                 case S_ALNUM:
201                         if(c == EOF) {
202                                 unget = EOF;
203                                 *tp = '\0';
204                                 return SYM;
205                         } else if(c == ':') {
206                                 *tp++ = c;
207                                 *tp = '\0';
208                                 return SYM;
209                                 break;
210                         } else if(flags & (IS_ALPHA|IS_NUM)) {
211                                 *tp++ = c;
212                                 break;
213                         } else {
214                                 unget = c;
215                                 *tp = '\0';
216                                 return SYM;
217                         }
218                         break;
219                 case S_NUM:
220                         if(c == EOF) {
221                                 unget = EOF;
222                                 *tp = '\0';
223                                 return dot_seen ? FRAC : CDEC;
224                         } else if((flags & IS_NUM) || (c == '.' && NOT dot_seen)) {
225                                 *tp++ = c;
226                                 if(c == '.') dot_seen = TRUE;
227                                 break;
228                         } else {
229                                 unget = c;
230                                 *tp = '\0';
231                                 return dot_seen ? FRAC : CDEC;
232                         }
233                         break;
234                 case S_CHAR:
235                         if(c == EOF) {
236                                 unget = EOF;
237                                 *tp = '\0';
238                                 return CHAR;
239                         } else if(c == '\\') {
240                                 state = S_ESC_CHAR;
241                         } else if(c == '\'') {
242                                 *tp = '\0';
243                                 return CHAR;
244                         } else {
245                                 *tp++ = c;
246                                 if(tp > tok + 1)
247                                         state = S_SQ_STRING;
248                         }
249                         break;
250                 case S_ESC_CHAR:
251                         if(c == EOF) {
252                                 unget = EOF;
253                                 *tp = '\0';
254                                 return CHAR;
255                         }
256                         switch(c) {
257                         case 'b': *tp = '\b'; break;
258                         case 'f': *tp = '\f'; break;
259                         case 'n': *tp = '\n'; break;
260                         case 'r': *tp = '\r'; break;
261                         case 't': *tp = '\t'; break;
262                         case '\\': *tp = '\\'; break;
263                         case '\'':
264                                 *tp = '\0';
265                                 return CHAR;
266                                 break;
267                         default:
268                                 *tp++ = c;
269                                 state = S_SQ_STRING;
270                                 break;
271                         }
272                         break;
273                 case S_SQ_STRING:
274                         if(c == EOF) {
275                                 unget = EOF;
276                                 *tp = '\0';
277                                 return STRING;
278                         } else if(c == '\'') {
279                                 *tp = '\0';
280                                 return STRING;
281                         } else {
282                                 *tp++ = c;
283                         }
284                         break;
285                 case S_DQ_STRING:
286                         if(c == EOF) {
287                                 unget = EOF;
288                                 *tp = '\0';
289                                 return STRING;
290                         } else if(c == '"') {
291                                 *tp = '\0';
292                                 return STRING;
293                         } else {
294                                 *tp++ = c;
295                         }
296                         break;
297                 } /* switch(state) */
298         } /* for(;;) */
299 }
300
301 struct ascii_tab ascii_tab[] = {
302         {"\\z00",       IS_NONE                                 /* 0x00 */},
303         {"\\z01",       IS_NONE                                 /* 0x01 */},
304         {"\\z02",       IS_NONE                                 /* 0x02 */},
305         {"\\z03",       IS_NONE                                 /* 0x03 */},
306         {"\\z04",       IS_NONE                                 /* 0x04 */},
307         {"\\z05",       IS_NONE                                 /* 0x05 */},
308         {"\\z06",       IS_NONE                                 /* 0x06 */},
309         {"\\z07",       IS_NONE                                 /* 0x07 */},
310         {"\\b",         IS_NONE                                 /* 0x08 */},
311         {"\\t",         IS_NONE|IS_WHITE                /* 0x09 */},
312         {"\\n",         IS_NONE                                 /* 0x0A */},
313         {"\\z0B",       IS_NONE                                 /* 0x0B */},
314         {"\\z0C",       IS_NONE                                 /* 0x0C */},
315         {"\\r",         IS_NONE                                 /* 0x0D */},
316         {"\\z0E",       IS_NONE                                 /* 0x0E */},
317         {"\\z0F",       IS_NONE                                 /* 0x0F */},
318         {"\\z10",       IS_NONE                                 /* 0x10 */},
319         {"\\z11",       IS_NONE                                 /* 0x11 */},
320         {"\\z12",       IS_NONE                                 /* 0x12 */},
321         {"\\z13",       IS_NONE                                 /* 0x13 */},
322         {"\\z14",       IS_NONE                                 /* 0x14 */},
323         {"\\z15",       IS_NONE                                 /* 0x15 */},
324         {"\\z16",       IS_NONE                                 /* 0x16 */},
325         {"\\z17",       IS_NONE                                 /* 0x17 */},
326         {"\\z18",       IS_NONE                                 /* 0x18 */},
327         {"\\z19",       IS_NONE                                 /* 0x19 */},
328         {"\\z1A",       IS_NONE                                 /* 0x1A */},
329         {"\\z1B",       IS_NONE                                 /* 0x1B */},
330         {"\\z1C",       IS_NONE                                 /* 0x1C */},
331         {"\\z1D",       IS_NONE                                 /* 0x1D */},
332         {"\\z1E",       IS_NONE                                 /* 0x1E */},
333         {"\\z1F",       IS_NONE                                 /* 0x1F */},
334         {" ",           IS_NONE|IS_WHITE                /* 0x20 */},
335         {"!",           IS_NONE                                 /* 0x21 */},
336         {"\"",          IS_NONE                                 /* 0x22 */},
337         {"#",           IS_NONE                                 /* 0x23 */},
338         {"$",           IS_NONE                                 /* 0x24 */},
339         {"%",           IS_NONE                                 /* 0x25 */},
340         {"&",           IS_NONE                                 /* 0x26 */},
341         {"'",           IS_NONE                                 /* 0x27 */},
342         {"(",           IS_NONE                                 /* 0x28 */},
343         {")",           IS_NONE                                 /* 0x29 */},
344         {"*",           IS_NONE                                 /* 0x2A */},
345         {"+",           IS_NONE                                 /* 0x2B */},
346         {",",           IS_NONE                                 /* 0x2C */},
347         {"-",           IS_NONE                                 /* 0x2D */},
348         {".",           IS_NONE                                 /* 0x2E */},
349         {"/",           IS_NONE                                 /* 0x2F */},
350         {"0",           IS_NONE|IS_NUM|IS_HEX   /* 0x30 */},
351         {"1",           IS_NONE|IS_NUM|IS_HEX   /* 0x31 */},
352         {"2",           IS_NONE|IS_NUM|IS_HEX   /* 0x32 */},
353         {"3",           IS_NONE|IS_NUM|IS_HEX   /* 0x33 */},
354         {"4",           IS_NONE|IS_NUM|IS_HEX   /* 0x34 */},
355         {"5",           IS_NONE|IS_NUM|IS_HEX   /* 0x35 */},
356         {"6",           IS_NONE|IS_NUM|IS_HEX   /* 0x36 */},
357         {"7",           IS_NONE|IS_NUM|IS_HEX   /* 0x37 */},
358         {"8",           IS_NONE|IS_NUM|IS_HEX   /* 0x38 */},
359         {"9",           IS_NONE|IS_NUM|IS_HEX   /* 0x39 */},
360         {":",           IS_NONE                                 /* 0x3A */},
361         {";",           IS_NONE                                 /* 0x3B */},
362         {"<",           IS_NONE                                 /* 0x3C */},
363         {"=",           IS_NONE                                 /* 0x3D */},
364         {">",           IS_NONE                                 /* 0x3E */},
365         {"?",           IS_NONE                                 /* 0x3F */},
366         {"@",           IS_NONE                                 /* 0x40 */},
367         {"A",           IS_NONE|IS_ALPHA|IS_HEX /* 0x41 */},
368         {"B",           IS_NONE|IS_ALPHA|IS_HEX /* 0x42 */},
369         {"C",           IS_NONE|IS_ALPHA|IS_HEX /* 0x43 */},
370         {"D",           IS_NONE|IS_ALPHA|IS_HEX /* 0x44 */},
371         {"E",           IS_NONE|IS_ALPHA|IS_HEX /* 0x45 */},
372         {"F",           IS_NONE|IS_ALPHA|IS_HEX /* 0x46 */},
373         {"G",           IS_NONE|IS_ALPHA                /* 0x47 */},
374         {"H",           IS_NONE|IS_ALPHA                /* 0x48 */},
375         {"I",           IS_NONE|IS_ALPHA                /* 0x49 */},
376         {"J",           IS_NONE|IS_ALPHA                /* 0x4A */},
377         {"K",           IS_NONE|IS_ALPHA                /* 0x4B */},
378         {"L",           IS_NONE|IS_ALPHA                /* 0x4C */},
379         {"M",           IS_NONE|IS_ALPHA                /* 0x4D */},
380         {"N",           IS_NONE|IS_ALPHA                /* 0x4E */},
381         {"O",           IS_NONE|IS_ALPHA                /* 0x4F */},
382         {"P",           IS_NONE|IS_ALPHA                /* 0x50 */},
383         {"Q",           IS_NONE|IS_ALPHA                /* 0x51 */},
384         {"R",           IS_NONE|IS_ALPHA                /* 0x52 */},
385         {"S",           IS_NONE|IS_ALPHA                /* 0x53 */},
386         {"T",           IS_NONE|IS_ALPHA                /* 0x54 */},
387         {"U",           IS_NONE|IS_ALPHA                /* 0x55 */},
388         {"V",           IS_NONE|IS_ALPHA                /* 0x56 */},
389         {"W",           IS_NONE|IS_ALPHA                /* 0x57 */},
390         {"X",           IS_NONE|IS_ALPHA                /* 0x58 */},
391         {"Y",           IS_NONE|IS_ALPHA                /* 0x59 */},
392         {"Z",           IS_NONE|IS_ALPHA                /* 0x5A */},
393         {"[",           IS_NONE                                 /* 0x5B */},
394         {"\\",          IS_NONE                                 /* 0x5C */},
395         {"]",           IS_NONE                                 /* 0x5D */},
396         {"^",           IS_NONE                                 /* 0x5E */},
397         {"_",           IS_NONE|IS_ALPHA                /* 0x5F */},
398         {"`",           IS_NONE                                 /* 0x60 */},
399         {"a",           IS_NONE|IS_ALPHA|IS_HEX /* 0x61 */},
400         {"b",           IS_NONE|IS_ALPHA|IS_HEX /* 0x62 */},
401         {"c",           IS_NONE|IS_ALPHA|IS_HEX /* 0x63 */},
402         {"d",           IS_NONE|IS_ALPHA|IS_HEX /* 0x64 */},
403         {"e",           IS_NONE|IS_ALPHA|IS_HEX /* 0x65 */},
404         {"f",           IS_NONE|IS_ALPHA|IS_HEX /* 0x66 */},
405         {"g",           IS_NONE|IS_ALPHA                /* 0x67 */},
406         {"h",           IS_NONE|IS_ALPHA                /* 0x68 */},
407         {"i",           IS_NONE|IS_ALPHA                /* 0x69 */},
408         {"j",           IS_NONE|IS_ALPHA                /* 0x6A */},
409         {"k",           IS_NONE|IS_ALPHA                /* 0x6B */},
410         {"l",           IS_NONE|IS_ALPHA                /* 0x6C */},
411         {"m",           IS_NONE|IS_ALPHA                /* 0x6D */},
412         {"n",           IS_NONE|IS_ALPHA                /* 0x6E */},
413         {"o",           IS_NONE|IS_ALPHA                /* 0x6F */},
414         {"p",           IS_NONE|IS_ALPHA                /* 0x70 */},
415         {"q",           IS_NONE|IS_ALPHA                /* 0x71 */},
416         {"r",           IS_NONE|IS_ALPHA                /* 0x72 */},
417         {"s",           IS_NONE|IS_ALPHA                /* 0x73 */},
418         {"t",           IS_NONE|IS_ALPHA                /* 0x74 */},
419         {"u",           IS_NONE|IS_ALPHA                /* 0x75 */},
420         {"v",           IS_NONE|IS_ALPHA                /* 0x76 */},
421         {"w",           IS_NONE|IS_ALPHA                /* 0x77 */},
422         {"x",           IS_NONE|IS_ALPHA                /* 0x78 */},
423         {"y",           IS_NONE|IS_ALPHA                /* 0x79 */},
424         {"z",           IS_NONE|IS_ALPHA                /* 0x7A */},
425         {"{",           IS_NONE                                 /* 0x7B */},
426         {"|",           IS_NONE                                 /* 0x7C */},
427         {"}",           IS_NONE                                 /* 0x7D */},
428         {"~",           IS_NONE                                 /* 0x7E */},
429         {"\\z7F",       IS_NONE                                 /* 0x7F */},
430 };
431
432
433 /**************** lgetc - returns next character *************************/
434
435 #define INLINE 1024
436
437 char line_buf[INLINE];
438 char *cur_line = line_buf;              /* points to current line buffer */
439 char *clp = NULL;                               /* where we're at in cur_line */
440
441 lgetc(fp)
442 FILE *fp;
443 {
444         int c;
445
446         if(clp == NULL) {
447                 if(fgets(cur_line, INLINE, fp) == NULL) {
448                         c = EOF;
449                 } else {
450                         clp = cur_line;
451                         c = *clp++;
452                 }
453         } else {
454                 c = *clp++;
455         }
456
457         switch(c) {
458         case EOF:
459                 /* at EOF: all done */
460                 if(ldebug)
461                         printf("<eof>\n");
462                 return EOF;
463                 break;
464         case '\0':
465                 c = '\n';
466         case '\n':
467                 clp = NULL;
468                 break;
469         default:
470                 break;
471         }
472
473         if(ldebug)
474                 printf(c < ' ' ? "<\\z%02X>%s" : "<%c>", c, c == '\n' ? "\n" : "");
475
476         return c;
477 }