Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/**********************************************************************
32
$Author: release $
33
$Date: 1998/01/17 15:57:23 $
34
$Revision: 1.1.1.1 $
35
$Log: lex.c,v $
36
 * Revision 1.1.1.1  1998/01/17  15:57:23  release
37
 * First version to be checked into rolling release.
38
 *
39
 * Revision 1.4  1995/09/05  16:27:49  currie
40
 * include files + 2r lex
41
 *
42
 * Revision 1.3  1995/08/15  16:14:38  currie
43
 * for build 4.0
44
 *
45
 * Revision 1.2  1995/06/08  09:13:51  currie
46
 * Added sigs to tokdecs/defs
47
 *
48
 * Revision 1.1  1995/04/07  14:29:07  currie
49
 * Initial revision
50
 *
51
 * Revision 1.1  1995/04/07  14:29:07  currie
52
 * Initial revision
53
 *
54
 * Revision 1.3  1994/12/05  10:13:02  currie
55
 * Extended size of input buffer
56
 *
57
 * Revision 1.2  1994/07/21  10:36:20  currie
58
 * Added banner
59
 *
60
***********************************************************************/
61
 
62
#include "config.h"
63
#include "util.h"
64
#include "defs.h"
65
#include "includes.h"
66
#include "syntax.h"
67
#include "reserved.h"
68
#include "consfile.h"
69
 
70
typedef struct FStack_struct{ FILE * file; char * fname; unsigned long line;
71
				struct FStack_struct * next; } FStack;
72
 
73
static FStack * fstack = (FStack*)0;
74
LEX lex_v;
75
FILE * in_file;
76
 
77
 
78
char buff[BUFFLEN];
79
int bind = -1;
80
 
81
static char lexeme[BUFFLEN+1];
82
unsigned long cLINE = 0;
83
static char numstr[BUFFLEN+1];
84
int lnum;
85
long radix;
86
 
87
 
88
static void push_current
89
    PROTO_Z ()
90
{
91
    FStack * x = MALLOC(FStack);
92
    x->file = in_file; x->fname = file_name;
93
    x->line = cLINE; x->next = fstack;
94
    fstack = x;
95
}
96
 
97
 
98
static void pop_current
99
    PROTO_Z ()
100
{
101
    in_file = fstack->file; file_name = fstack->fname;
102
    cLINE = fstack->line;
103
    fstack = fstack->next;
104
}
105
 
106
 
107
static int directive
108
    PROTO_Z ()
109
{
110
    if (buff[0] == '#') {
111
	char c = buff[8];
112
   	buff[8] = 0;
113
   	if (strcmp(buff+1,"include")==0) {
114
	    push_current();
115
	    in_file = open_include(buff+9);
116
	    bind = -1;
117
	    cLINE = 0;
118
	    return 1;
119
   	}
120
   	buff[8] = c;
121
    }
122
    return 0;
123
}
124
 
125
 
126
static LEX symbol
127
    PROTO_N ( (s) )
128
    PROTO_T ( int s )
129
{
130
    LEX l;
131
    l.t = s;
132
    return l;
133
}
134
 
135
 
136
static int mygetc
137
    PROTO_Z ()
138
{
139
    while(bind<0 || buff[bind]==0) {
140
     	cLINE++;
141
	if (fgets(buff, BUFFLEN, in_file) == 0) {
142
	    if (fstack == (FStack *)0) return -1;
143
	    pop_current();
144
	} else {
145
	    if (directive()!=1) bind = 0;
146
	}
147
     }
148
     return(buff[bind++]);
149
}
150
 
151
 
152
static int string_char
153
    PROTO_N ( (q) )
154
    PROTO_T ( int q )
155
{
156
    int c = mygetc();
157
    switch (c) {
158
	case '\\': {
159
	    c = mygetc();
160
	    if (c=='t') return '\t';
161
	    if (c=='n') return '\n';
162
	    if (c=='r') return '\r';
163
	    return c;
164
	}
165
	case '"': {
166
	    if(q) return -1;
167
	    break ;
168
	}
169
    }
170
    return c;
171
}
172
 
173
 
174
static LEX charval
175
    PROTO_Z ()
176
{
177
    LEX l;
178
    l.t = lex_character;
179
    l.val.v = string_char(0);
180
    if (mygetc()!= '\'') fail("Unmatched quote");
181
    return l;
182
}
183
 
184
 
185
static LEX stringval
186
    PROTO_Z ()
187
{
188
    LEX l;
189
    l.t = lex_qstring;
190
    l.val.name = "";
191
    for(;;) {
192
	int i;
193
	for(i=0; i<BUFFLEN; i++) {
194
	    int c = string_char(1);
195
	    if (c<0) {
196
		lexeme[i] = 0;
197
		l.val.name = append_string(l.val.name, lexeme);
198
		return l;
199
	    }
200
	    lexeme[i]= (char)c;
201
	}
202
	lexeme[i] = 0;
203
	l.val.name = append_string(l.val.name, lexeme);
204
    }
205
}
206
 
207
 
208
static int terminator
209
    PROTO_N ( (x, number) )
210
    PROTO_T ( int x X int number )
211
{
212
    switch (x) {
213
  	case '(': case ')': case '[': case ']': case '{':
214
  	case '}': case ':': case ';': case ',': case ' ':
215
  	case 0: case '\t': case '\n': case '\'': case '"': case -1: {
216
	    return 1;
217
	}
218
  	case '0': case '1': case '2': case '3': case '4':
219
	case '5': case '6': case '7': case '8': case '9': {
220
	    return number;
221
	}
222
    }
223
    return 0;
224
}
225
 
226
 
227
static LEX term_val
228
    PROTO_N ( (i) )
229
    PROTO_T ( int i )
230
{
231
    LEX l;
232
    l.t = terminals[i].t;
233
    l.val.name = terminals[i].name;
234
    return l;
235
}
236
 
237
 
238
static LEX cons_val
239
    PROTO_N ( (i) )
240
    PROTO_T ( int i )
241
{
242
    LEX l;
243
    l.t = constructs[i].t;
244
    l.val.v = i;
245
    return l;
246
}
247
 
248
 
249
static LEX id_val
250
    PROTO_N ( (id) )
251
    PROTO_T ( char * id )
252
{
253
    LEX l;
254
    l.t = lex_ident;
255
    l.val.name = copy_string(id);
256
    return l;
257
}
258
 
259
 
260
static LEX tok_val
261
    PROTO_N ( (td) )
262
    PROTO_T ( Tokdec * td )
263
{
264
    LEX l;
265
    int st = td->sort.ressort.sort;
266
    l.val.tokname = td;
267
    again:
268
    switch(st) {
269
	case access_sort: l.t = access_tok; break ;
270
	case alignment_sort: l.t = alignment_tok; break;
271
	case al_tag_sort: l.t = al_tag_tok; break;
272
	case bitfield_variety_sort: l.t = bitfield_variety_tok; break;
273
	case bool_sort: l.t = bool_tok; break;
274
	case error_treatment_sort: l.t = error_treatment_tok; break;
275
	case exp_sort: l.t =  exp_tok; break;
276
	case floating_variety_sort: l.t = floating_variety_tok; break ;
277
	case label_sort: l.t = label_tok; break;
278
	case nat_sort: l.t = nat_tok; break;
279
	case ntest_sort: l.t = ntest_tok; break ;
280
	case rounding_mode_sort: l.t =rounding_mode_tok; break;
281
	case shape_sort: l.t=shape_tok; break;
282
	case signed_nat_sort: l.t = signed_nat_tok; break ;
283
	case string_sort: l.t = string_tok; break;
284
	case tag_sort: l.t = tag_tok; break;
285
	case transfer_mode_sort: l.t = transfer_mode_tok; break;
286
	case variety_sort: l.t=variety_tok; break;
287
	case token_sort: {
288
	    st = td->sort.ressort.toksort->ressort.sort;
289
	    goto again;
290
	}
291
	default: fail("Not a legal sort"); break;
292
    }
293
    return l;
294
}
295
 
296
 
297
static LEX decode
298
    PROTO_N ( (id) )
299
    PROTO_T ( char * id )
300
{
301
    int lower = 0;
302
    int upper = no_of_terminals-1;
303
    int mid;
304
    int cl,cu,cm;
305
    Tokdec * td;
306
 
307
    cl = strcmp(terminals[lower].name, id);
308
    if (cl == 0) return term_val(lower);
309
    if (cl > 0) goto notterm;
310
    cu = strcmp(terminals[upper].name, id);
311
    if (cu == 0) return term_val(upper);
312
    if (cu < 0) goto notterm;
313
    while ( (mid = (upper+lower)/2), upper-lower > 1) {
314
	cm = strcmp(terminals[mid].name, id);
315
	if (cm == 0) return term_val(mid);
316
	if ((cm ^ cl) >= 0) {
317
	    lower = mid;
318
	} else if ((cm ^ cu) >= 0) {
319
	    upper = mid;
320
	} else {
321
	    break;
322
	}
323
    }
324
 
325
    notterm:
326
    lower = 0;
327
    upper = no_of_cons-1;
328
    cl = strcmp(constructs[lower].name, id);
329
    if (cl == 0) return cons_val(lower);
330
    if (cl > 0) goto notcons;
331
    cu = strcmp(constructs[upper].name, id);
332
    if (cu == 0) return cons_val(upper);
333
    if (cu < 0) goto notcons;
334
    while ( (mid = (upper+lower)/2), upper-lower > 1 ) {
335
	cm = strcmp(constructs[mid].name, id);
336
	if (cm == 0) return cons_val(mid);
337
	if ((cm ^ cl) >= 0) {
338
	    lower = mid;
339
	} else if ((cm ^ cu) >= 0) {
340
	    upper = mid;
341
	} else {
342
	    break;
343
	}
344
    }
345
 
346
    notcons:
347
    if (search_for_toks) {
348
	td = tokdecs;
349
	while(td != (Tokdec*)0) {
350
	    if (strcmp(id, td->idname.id)==0) {
351
		return tok_val(td);
352
	    }
353
	    td = td->next;
354
	}
355
    }
356
    return id_val(id);
357
}
358
 
359
 
360
char * fformat
361
    PROTO_N ( (s, l) )
362
    PROTO_T ( char * s X int l )
363
{
364
    int i;
365
    for(i=0; i<l; i++) {
366
  	char c = s[i];
367
	if (c>='a' && c<= 'f') {
368
	    s[i] = (char)(c-'a'+10+'0');
369
	} else if (c>='A' && c<= 'F') {
370
	    s[i] = (char)(c-'A'+10+'0');
371
	}
372
    }
373
    return s;
374
}
375
 
376
 
377
long stoi
378
    PROTO_N ( (s, n) )
379
    PROTO_T ( char * s X int n )
380
{
381
    long ans = 0;
382
    int i;
383
    for(i=0; i<n; i++) {
384
	int x = s[i];
385
  	int d = (x>='0' && x<='9')? x-'0':
386
  		(x>='a' && x<='f')? x-'a'+10: x-'A'+10;
387
  	ans = ans*radix+d;
388
    }
389
    return ans;
390
}
391
 
392
 
393
static LEX numval
394
    PROTO_N ( (c) )
395
    PROTO_T ( int c )
396
{
397
    int isfloat = 0;
398
    char x;
399
    LEX l;
400
    radix = 10;
401
    lnum = 0;
402
    for(;;) {
403
	numstr[lnum++]= (char)c;
404
	switch (x=buff[bind]) {
405
	    case '0': case '1': case '2': case '3': case '4':
406
	    case '5': case '6': case '7': case '8': case '9': {
407
		if(x-'0'>=radix) break;
408
		c = mygetc();
409
		continue;
410
	    }
411
	    case 'a': case 'b': case 'c':
412
	    case 'd': case 'e': case 'f': {
413
		if(x-'a'+10>=radix) break;
414
		c = mygetc();
415
		continue;
416
	    }
417
	    case 'A': case 'B': case 'C':
418
	    case 'D': case 'E': case 'F': {
419
		if(x-'A'+10>=radix) break;
420
		c = mygetc();
421
		continue;
422
	    }
423
	    case 'r': case 'R': {
424
		if (isfloat) break;
425
		radix = stoi(&numstr[0], lnum);
426
		lnum = 0;
427
		IGNORE mygetc();
428
		switch (x=buff[bind]) {
429
		    case '0': case '1': case '2': case '3': case '4':
430
		    case '5': case '6': case '7': case '8': case '9': {
431
			if(x-'0' < radix) {
432
			    c = mygetc();
433
			    continue;
434
			}
435
			break;
436
		    }
437
		    case 'a': case 'b': case 'c':
438
		    case 'd': case 'e': case 'f': {
439
			if(x-'a'+10< radix) {
440
			    c = mygetc();
441
			    continue;
442
			}
443
			break;
444
		    }
445
		}
446
		break;
447
	    }
448
	    case '.': {
449
		if (isfloat) break;
450
		isfloat=1;
451
		c=mygetc();
452
		continue;
453
	    }
454
        }
455
        break;
456
   }
457
   l.t = (isfloat)?lex_float__den:lex_int__den;
458
   l.val.name = &numstr[0];
459
   return l;
460
}
461
 
462
 
463
LEX reader
464
    PROTO_Z ()
465
{
466
    int c;
467
    int ll;
468
 
469
    again:
470
    switch (c = mygetc()) {
471
	case '(': return symbol(lex_ord);
472
  	case ')': return symbol(lex_crd);
473
  	case '[': return symbol(lex_osq);
474
  	case ']': return symbol(lex_csq);
475
  	case '{': return symbol(lex_ocurl);
476
  	case '}': return symbol(lex_ccurl);
477
  	case ':': return symbol(lex_colon);
478
  	case ';': return symbol(lex_semi);
479
  	case ',': return symbol(lex_comma);
480
 
481
  	case '0': case '1': case '2': case '3': case '4':
482
	case '5': case '6': case '7': case '8': case '9': {
483
	    return numval(c);
484
	}
485
 
486
  	case ' ': case 0: case '\t': case '\n': case '\r': {
487
	    goto again;
488
	}
489
 
490
  	case '\'': return charval();
491
  	case '"' : return stringval();
492
  	case -1: return symbol(lex_eof);
493
 
494
	default: {
495
	    int number = (c=='-' || c=='.');
496
	    ll = 0;
497
	    while (ll < BUFFLEN){
498
     		lexeme[ll++] = (char)c;
499
     		if (terminator(buff[bind], number)) break;
500
     		number = 0;
501
     		c = mygetc();
502
	    }
503
	    lexeme[ll] = 0;
504
	    if (ll==1) {
505
		switch(c) {
506
		    case '=': return symbol(lex_equals);
507
		    case '|': return symbol(lex_bar);
508
		    case '.': return symbol(lex_point);
509
		    case '?': return symbol(lex_query);
510
		    case '#': return symbol(lex_hash);
511
		}
512
	    }
513
	    if (strcmp(&lexeme[0],"/*")==0) {
514
     		int n = 1;
515
     		for(;;) {
516
		    c = mygetc();
517
		    while (c=='*') {
518
			c = mygetc();
519
			if (c == '/') {
520
			    if (--n == 0) goto again;
521
			    c = mygetc();
522
			}
523
		    }
524
		    if (c=='/') {
525
			c = mygetc();
526
			if (c=='*') n++;
527
		    }
528
		}
529
	    }
530
	    return decode(lexeme);
531
	}
532
    }
533
}
534
 
535
 
536
void skip_term
537
    PROTO_N ( (c) )
538
    PROTO_T ( int c )
539
{
540
    if (lex_v.t != c) {
541
	char *s = "?" ;
542
	switch ( c ) {
543
	    case lex_osq : s = "[" ; break ;
544
	    case lex_csq : s = "]" ; break ;
545
	    case lex_ord : s = "(" ; break ;
546
	    case lex_crd : s = ")" ; break ;
547
	    case lex_comma : s = "," ; break ;
548
	}
549
	fail ( "Syntax error, '%s' expected", s ) ;
550
    }
551
    lex_v = reader() ;
552
}