Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
6 7u83 1
/*
2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
32
    		 Crown Copyright (c) 1997
33
 
34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
42
 
43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
45
 
46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
49
 
50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
53
 
54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
/**********************************************************************
62
$Author: release $
63
$Date: 1998/01/17 15:57:23 $
64
$Revision: 1.1.1.1 $
65
$Log: lex.c,v $
66
 * Revision 1.1.1.1  1998/01/17  15:57:23  release
67
 * First version to be checked into rolling release.
68
 *
69
 * Revision 1.4  1995/09/05  16:27:49  currie
70
 * include files + 2r lex
71
 *
72
 * Revision 1.3  1995/08/15  16:14:38  currie
73
 * for build 4.0
74
 *
75
 * Revision 1.2  1995/06/08  09:13:51  currie
76
 * Added sigs to tokdecs/defs
77
 *
78
 * Revision 1.1  1995/04/07  14:29:07  currie
79
 * Initial revision
80
 *
81
 * Revision 1.1  1995/04/07  14:29:07  currie
82
 * Initial revision
83
 *
84
 * Revision 1.3  1994/12/05  10:13:02  currie
85
 * Extended size of input buffer
86
 *
87
 * Revision 1.2  1994/07/21  10:36:20  currie
88
 * Added banner
89
 *
90
***********************************************************************/
91
 
92
#include "config.h"
93
#include "util.h"
94
#include "defs.h"
95
#include "includes.h"
96
#include "lex.h"
97
#include "syntax.h"
98
#include "reserved.h"
99
#include "consfile.h"
100
 
101
typedef struct FStack_struct{
102
	FILE *file;
103
	char *fname;
104
	unsigned long line;
105
	struct FStack_struct *next;
106
} FStack;
107
 
108
static FStack *fstack = (FStack *)0;
109
LEX lex_v;
110
FILE *in_file;
111
 
112
 
113
char buff[BUFFLEN];
114
int bind = -1;
115
 
116
static char lexeme[BUFFLEN + 1];
117
unsigned long cLINE = 0;
118
static char numstr[BUFFLEN + 1];
119
int lnum;
120
long radix;
121
 
122
 
123
static void
124
push_current(void)
125
{
126
	FStack *x = MALLOC(FStack);
127
	x->file = in_file;
128
	x->fname = file_name;
129
	x->line = cLINE;
130
	x->next = fstack;
131
	fstack = x;
132
}
133
 
134
 
135
static void
136
pop_current(void)
137
{
138
	in_file = fstack->file;
139
	file_name = fstack->fname;
140
	cLINE = fstack->line;
141
	fstack = fstack->next;
142
}
143
 
144
 
145
static int
146
directive(void)
147
{
148
	if (buff[0] == '#') {
149
		char c = buff[8];
150
		buff[8] = 0;
151
		if (strcmp(buff + 1, "include") ==0) {
152
			push_current();
153
			in_file = open_include(buff + 9);
154
			bind = -1;
155
			cLINE = 0;
156
			return 1;
157
		}
158
		buff[8] = c;
159
	}
160
	return 0;
161
}
162
 
163
 
164
static LEX
165
symbol(int s)
166
{
167
	LEX l;
168
	l.t = s;
169
	return l;
170
}
171
 
172
 
173
static int
174
mygetc(void)
175
{
176
	while (bind<0 || buff[bind] ==0) {
177
		cLINE++;
178
		if (fgets(buff, BUFFLEN, in_file) == 0) {
179
			if (fstack == (FStack *)0) return -1;
180
			pop_current();
181
		} else {
182
			if (directive() !=1) {
183
				bind = 0;
184
			}
185
		}
186
	}
187
	return(buff[bind++]);
188
}
189
 
190
 
191
static int
192
string_char(int q)
193
{
194
	int c = mygetc();
195
	switch (c) {
196
	case '\\': {
197
		c = mygetc();
198
		if (c == 't') {
199
			return '\t';
200
		}
201
		if (c == 'n') {
202
			return '\n';
203
		}
204
		if (c == 'r') {
205
			return '\r';
206
		}
207
		return c;
208
	}
209
	case '"':
210
		if (q) {
211
			return -1;
212
		}
213
		break;
214
	}
215
	return c;
216
}
217
 
218
 
219
static LEX
220
charval(void)
221
{
222
	LEX l;
223
	l.t = lex_character;
224
	l.val.v = string_char(0);
225
	if (mygetc() != '\'') {
226
		fail("Unmatched quote");
227
	}
228
	return l;
229
}
230
 
231
 
232
static LEX
233
stringval(void)
234
{
235
	LEX l;
236
	l.t = lex_qstring;
237
	l.val.name = "";
238
	for (;;) {
239
		int i;
240
		for (i = 0; i<BUFFLEN; i++) {
241
			int c = string_char(1);
242
			if (c < 0) {
243
				lexeme[i] = 0;
244
				l.val.name = append_string(l.val.name, lexeme);
245
				return l;
246
			}
247
			lexeme[i] = (char)c;
248
		}
249
		lexeme[i] = 0;
250
		l.val.name = append_string(l.val.name, lexeme);
251
	}
252
}
253
 
254
 
255
static int
256
terminator(int x, int number)
257
{
258
	switch (x) {
259
	case '(':
260
	case ')':
261
	case '[':
262
	case ']':
263
	case '{':
264
	case '}':
265
	case ':':
266
	case ';':
267
	case ',':
268
	case ' ':
269
	case 0:
270
	case '\t':
271
	case '\n':
272
	case '\'':
273
	case '"':
274
	case -1:
275
		return 1;
276
	case '0':
277
	case '1':
278
	case '2':
279
	case '3':
280
	case '4':
281
	case '5':
282
	case '6':
283
	case '7':
284
	case '8':
285
	case '9':
286
		return number;
287
	}
288
	return 0;
289
}
290
 
291
 
292
static LEX
293
term_val(int i)
294
{
295
	LEX l;
296
	l.t = terminals[i].t;
297
	l.val.name = terminals[i].name;
298
	return l;
299
}
300
 
301
 
302
static LEX
303
cons_val(int i)
304
{
305
	LEX l;
306
	l.t = constructs[i].t;
307
	l.val.v = i;
308
	return l;
309
}
310
 
311
 
312
static LEX
313
id_val(char *id)
314
{
315
	LEX l;
316
	l.t = lex_ident;
317
	l.val.name = copy_string(id);
318
	return l;
319
}
320
 
321
 
322
static LEX
323
tok_val(Tokdec *td)
324
{
325
	LEX l;
326
	int st = td->sort.ressort.sort;
327
	l.val.tokname = td;
328
again:
329
	switch (st) {
330
	case access_sort:
331
		l.t = access_tok;
332
		break;
333
	case alignment_sort:
334
		l.t = alignment_tok;
335
		break;
336
	case al_tag_sort:
337
		l.t = al_tag_tok;
338
		break;
339
	case bitfield_variety_sort:
340
		l.t = bitfield_variety_tok;
341
		break;
342
	case bool_sort:
343
		l.t = bool_tok;
344
		break;
345
	case error_treatment_sort:
346
		l.t = error_treatment_tok;
347
		break;
348
	case exp_sort:
349
		l.t = exp_tok;
350
		break;
351
	case floating_variety_sort:
352
		l.t = floating_variety_tok;
353
		break;
354
	case label_sort:
355
		l.t = label_tok;
356
		break;
357
	case nat_sort:
358
		l.t = nat_tok;
359
		break;
360
	case ntest_sort:
361
		l.t = ntest_tok;
362
		break;
363
	case rounding_mode_sort:
364
		l.t = rounding_mode_tok;
365
		break;
366
	case shape_sort:
367
		l.t=shape_tok;
368
		break;
369
	case signed_nat_sort:
370
		l.t = signed_nat_tok;
371
		break;
372
	case string_sort:
373
		l.t = string_tok;
374
		break;
375
	case tag_sort:
376
		l.t = tag_tok;
377
		break;
378
	case transfer_mode_sort:
379
		l.t = transfer_mode_tok;
380
		break;
381
	case variety_sort:
382
		l.t=variety_tok;
383
		break;
384
	case token_sort: {
385
		st = td->sort.ressort.toksort->ressort.sort;
386
		goto again;
387
	}
388
	default:
389
		fail("Not a legal sort");
390
		break;
391
	}
392
	return l;
393
}
394
 
395
 
396
static LEX
397
decode(char *id)
398
{
399
	int lower = 0;
400
	int upper = no_of_terminals - 1;
401
	int mid;
402
	int cl, cu, cm;
403
	Tokdec *td;
404
 
405
	cl = strcmp(terminals[lower].name, id);
406
	if (cl == 0) {
407
		return term_val(lower);
408
	}
409
	if (cl > 0) {
410
		goto notterm;
411
	}
412
	cu = strcmp(terminals[upper].name, id);
413
	if (cu == 0) {
414
		return term_val(upper);
415
	}
416
	if (cu < 0) {
417
		goto notterm;
418
	}
419
	while ((mid = (upper + lower) / 2), upper-lower > 1) {
420
		cm = strcmp(terminals[mid].name, id);
421
		if (cm == 0) {
422
			return term_val(mid);
423
		}
424
		if ((cm ^ cl) >= 0) {
425
			lower = mid;
426
		} else if ((cm ^ cu) >= 0) {
427
			upper = mid;
428
		} else {
429
			break;
430
		}
431
	}
432
 
433
notterm:
434
	lower = 0;
435
	upper = no_of_cons - 1;
436
	cl = strcmp(constructs[lower].name, id);
437
	if (cl == 0) {
438
		return cons_val(lower);
439
	}
440
	if (cl > 0) {
441
		goto notcons;
442
	}
443
	cu = strcmp(constructs[upper].name, id);
444
	if (cu == 0) {
445
		return cons_val(upper);
446
	}
447
	if (cu < 0) {
448
		goto notcons;
449
	}
450
	while ((mid = (upper + lower) / 2), upper-lower > 1) {
451
		cm = strcmp(constructs[mid].name, id);
452
		if (cm == 0) {
453
			return cons_val(mid);
454
		}
455
		if ((cm ^ cl) >= 0) {
456
			lower = mid;
457
		} else if ((cm ^ cu) >= 0) {
458
			upper = mid;
459
		} else {
460
			break;
461
		}
462
	}
463
 
464
notcons:
465
	if (search_for_toks) {
466
		td = tokdecs;
467
		while (td != (Tokdec *)0) {
468
			if (strcmp(id, td->idname.id) == 0) {
469
				return tok_val(td);
470
			}
471
			td = td->next;
472
		}
473
	}
474
	return id_val(id);
475
}
476
 
477
 
478
char *
479
fformat(char *s, int l)
480
{
481
	int i;
482
	for (i = 0; i < l; i++) {
483
		char c = s[i];
484
		if (c >= 'a' && c <= 'f') {
485
			s[i] = (char)(c - 'a' + 10 + '0');
486
		} else if (c >= 'A' && c <= 'F') {
487
			s[i] = (char)(c - 'A' + 10 + '0');
488
		}
489
	}
490
	return s;
491
}
492
 
493
 
494
long
495
stoi(char *s, int n)
496
{
497
	long ans = 0;
498
	int i;
499
	for (i = 0; i < n; i++) {
500
		int x = s[i];
501
		int d = (x >= '0' && x <= '9') ? x- '0' :
502
		    (x >= 'a' && x <= 'f') ? x - 'a' + 10 : x - 'A' + 10;
503
		ans = ans*radix+d;
504
	}
505
	return ans;
506
}
507
 
508
 
509
static LEX
510
numval(int c)
511
{
512
	int isfloat = 0;
513
	char x;
514
	LEX l;
515
	radix = 10;
516
	lnum = 0;
517
	for (;;) {
518
		numstr[lnum++] = (char)c;
519
		switch (x = buff[bind]) {
520
		case '0':
521
		case '1':
522
		case '2':
523
		case '3':
524
		case '4':
525
		case '5':
526
		case '6':
527
		case '7':
528
		case '8':
529
		case '9': {
530
			if (x - '0' >= radix) {
531
				break;
532
			}
533
			c = mygetc();
534
			continue;
535
		}
536
		case 'a':
537
		case 'b':
538
		case 'c':
539
		case 'd':
540
		case 'e':
541
		case 'f': {
542
			if (x - 'a' + 10 >= radix) {
543
				break;
544
			}
545
			c = mygetc();
546
			continue;
547
		}
548
		case 'A':
549
		case 'B':
550
		case 'C':
551
		case 'D':
552
		case 'E':
553
		case 'F': {
554
			if (x - 'A' + 10 >= radix) {
555
				break;
556
			}
557
			c = mygetc();
558
			continue;
559
		}
560
		case 'r':
561
		case 'R': {
562
			if (isfloat) {
563
				break;
564
			}
565
			radix = stoi(&numstr[0], lnum);
566
			lnum = 0;
567
			IGNORE mygetc();
568
			switch (x = buff[bind]) {
569
			case '0':
570
			case '1':
571
			case '2':
572
			case '3':
573
			case '4':
574
			case '5':
575
			case '6':
576
			case '7':
577
			case '8':
578
			case '9': {
579
				if (x - '0' < radix) {
580
					c = mygetc();
581
					continue;
582
				}
583
				break;
584
			}
585
			case 'a':
586
			case 'b':
587
			case 'c':
588
			case 'd':
589
			case 'e':
590
			case 'f': {
591
				if (x - 'a' + 10 < radix) {
592
					c = mygetc();
593
					continue;
594
				}
595
				break;
596
			}
597
			}
598
			break;
599
		}
600
		case '.': {
601
			if (isfloat) {
602
				break;
603
			}
604
			isfloat = 1;
605
			c = mygetc();
606
			continue;
607
		}
608
		}
609
		break;
610
	}
611
	l.t = (isfloat) ? lex_float__den : lex_int__den;
612
	l.val.name = &numstr[0];
613
	return l;
614
}
615
 
616
 
617
LEX
618
reader(void)
619
{
620
	int c;
621
	int ll;
622
 
623
again:
624
	switch (c = mygetc()) {
625
	case '(':
626
		return symbol(lex_ord);
627
	case ')':
628
		return symbol(lex_crd);
629
	case '[':
630
		return symbol(lex_osq);
631
	case ']':
632
		return symbol(lex_csq);
633
	case '{':
634
		return symbol(lex_ocurl);
635
	case '}':
636
		return symbol(lex_ccurl);
637
	case ':':
638
		return symbol(lex_colon);
639
	case ';':
640
		return symbol(lex_semi);
641
	case ',':
642
		return symbol(lex_comma);
643
 
644
	case '0':
645
	case '1':
646
	case '2':
647
	case '3':
648
	case '4':
649
	case '5':
650
	case '6':
651
	case '7':
652
	case '8':
653
	case '9':
654
		return numval(c);
655
 
656
	case ' ':
657
	case 0:
658
	case '\t':
659
	case '\n':
660
	case '\r':
661
		goto again;
662
 
663
	case '\'':
664
		return charval();
665
	case '"':
666
		return stringval();
667
	case -1:
668
		return symbol(lex_eof);
669
 
670
	default: {
671
		int number = (c == '-' || c == '.');
672
		ll = 0;
673
		while (ll < BUFFLEN) {
674
			lexeme[ll++] = (char)c;
675
			if (terminator(buff[bind], number)) {
676
				break;
677
			}
678
			number = 0;
679
			c = mygetc();
680
		}
681
		lexeme[ll] = 0;
682
		if (ll == 1) {
683
			switch (c) {
684
			case '=':
685
				return symbol(lex_equals);
686
			case '|':
687
				return symbol(lex_bar);
688
			case '.':
689
				return symbol(lex_point);
690
			case '?':
691
				return symbol(lex_query);
692
			case '#':
693
				return symbol(lex_hash);
694
			}
695
		}
696
		if (strcmp(&lexeme[0], "/*") == 0) {
697
			int n = 1;
698
			for(;;) {
699
				c = mygetc();
700
				while (c == '*') {
701
					c = mygetc();
702
					if (c == '/') {
703
						if (--n == 0) {
704
							goto again;
705
						}
706
						c = mygetc();
707
					}
708
				}
709
				if (c == '/') {
710
					c = mygetc();
711
					if (c == '*') {
712
						n++;
713
					}
714
				}
715
			}
716
		}
717
		return decode(lexeme);
718
	}
719
	}
720
}
721
 
722
 
723
void
724
skip_term(int c)
725
{
726
	if (lex_v.t != c) {
727
		char *s = "?";
728
		switch ( c ) {
729
		case lex_osq:
730
			s = "[";
731
			break;
732
		case lex_csq:
733
			s = "]";
734
			break;
735
		case lex_ord:
736
			s = "(";
737
			break;
738
		case lex_crd:
739
			s = ")";
740
			break;
741
		case lex_comma:
742
			s = ",";
743
			break;
744
		}
745
		fail("Syntax error, '%s' expected", s);
746
	}
747
	lex_v = reader();
748
}