Subversion Repositories planix.SVN

Rev

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

Rev Author Line No. Line
2 - 1
# include "ldefs.h"
2
uchar *
3
getl(uchar *p)	/* return next line of input, throw away trailing '\n' */
4
	/* returns 0 if eof is had immediately */
5
{
6
	int c;
7
	uchar *s, *t;
8
 
9
	t = s = p;
10
	while(((c = gch()) != 0) && c != '\n')
11
		*t++ = c;
12
	*t = 0;
13
	if(c == 0 && s == t) return((uchar *)0);
14
	prev = '\n';
15
	pres = '\n';
16
	return(s);
17
}
18
 
19
void
20
printerr(char *type, char *fmt, va_list argl)
21
{
22
	char buf[1024];
23
 
24
	if(!eof)fprint(errorf,"%s:%d  ", yyfile, yyline);
25
	fprint(errorf,"(%s) ", type);
26
	vseprint(buf, buf+sizeof(buf), fmt, argl);
27
	fprint(errorf, "%s\n", buf);
28
}
29
 
30
 
31
void
32
error(char *s,...)
33
{
34
	va_list argl;
35
 
36
	va_start(argl, s);
37
	printerr("Error", s, argl);
38
	va_end(argl);
39
# ifdef DEBUG
40
	if(debug && sect != ENDSECTION) {
41
		sect1dump();
42
		sect2dump();
43
	}
44
# endif
45
	if(
46
# ifdef DEBUG
47
		debug ||
48
# endif
49
		report == 1) statistics();
50
	exits("error");	/* error return code */
51
}
52
 
53
void
54
warning(char *s,...)
55
{
56
	va_list argl;
57
 
58
	va_start(argl, s);
59
	printerr("Warning", s, argl);
60
	va_end(argl);
61
	Bflush(&fout);
62
}
63
 
64
void
65
lgate(void)
66
{
67
	int fd;
68
 
69
	if (lgatflg) return;
70
	lgatflg=1;
71
	if(foutopen == 0){
72
		fd = create("lex.yy.c", OWRITE, 0666);
73
		if(fd < 0)
74
			error("Can't open lex.yy.c: %r");
75
		Binit(&fout, fd, OWRITE);
76
		foutopen = 1;
77
		}
78
	phead1();
79
}
80
 
81
void
82
cclinter(int sw)
83
{
84
		/* sw = 1 ==> ccl */
85
	int i, j, k;
86
	int m;
87
	if(!sw){		/* is NCCL */
88
		for(i=1;i<NCH;i++)
89
			symbol[i] ^= 1;			/* reverse value */
90
	}
91
	for(i=1;i<NCH;i++)
92
		if(symbol[i]) break;
93
	if(i >= NCH) return;
94
	i = cindex[i];
95
	/* see if ccl is already in our table */
96
	j = 0;
97
	if(i){
98
		for(j=1;j<NCH;j++){
99
			if((symbol[j] && cindex[j] != i) ||
100
			   (!symbol[j] && cindex[j] == i)) break;
101
		}
102
	}
103
	if(j >= NCH) return;		/* already in */
104
	m = 0;
105
	k = 0;
106
	for(i=1;i<NCH;i++)
107
		if(symbol[i]){
108
			if(!cindex[i]){
109
				cindex[i] = ccount;
110
				symbol[i] = 0;
111
				m = 1;
112
			} else k = 1;
113
		}
114
			/* m == 1 implies last value of ccount has been used */
115
	if(m)ccount++;
116
	if(k == 0) return;	/* is now in as ccount wholly */
117
	/* intersection must be computed */
118
	for(i=1;i<NCH;i++){
119
		if(symbol[i]){
120
			m = 0;
121
			j = cindex[i];	/* will be non-zero */
122
			for(k=1;k<NCH;k++){
123
				if(cindex[k] == j){
124
					if(symbol[k]) symbol[k] = 0;
125
					else {
126
						cindex[k] = ccount;
127
						m = 1;
128
					}
129
				}
130
			}
131
			if(m)ccount++;
132
		}
133
	}
134
}
135
 
136
int
137
usescape(int c)
138
{
139
	int d;
140
	switch(c){
141
	case 'n': c = '\n'; break;
142
	case 'r': c = '\r'; break;
143
	case 't': c = '\t'; break;
144
	case 'b': c = '\b'; break;
145
	case 'f': c = 014; break;		/* form feed for ascii */
146
	case '0': case '1': case '2': case '3':
147
	case '4': case '5': case '6': case '7':
148
		c -= '0';
149
		while('0' <= (d=gch()) && d <= '7'){
150
			c = c * 8 + (d-'0');
151
			if(!('0' <= peek && peek <= '7')) break;
152
			}
153
		break;
154
	}
155
	return(c);
156
}
157
 
158
int
159
lookup(uchar *s, uchar **t)
160
{
161
	int i;
162
	i = 0;
163
	while(*t){
164
		if(strcmp((char *)s, *(char **)t) == 0)
165
			return(i);
166
		i++;
167
		t++;
168
	}
169
	return(-1);
170
}
171
 
172
int
173
cpyact(void)
174
{ /* copy C action to the next ; or closing } */
175
	int brac, c, mth;
176
	int savline, sw;
177
	char *savfile;
178
 
179
	brac = 0;
180
	sw = TRUE;
181
	savline = 0;
182
	savfile = "?";
183
 
184
while(!eof){
185
	c = gch();
186
swt:
187
	switch( c ){
188
 
189
case '|':	if(brac == 0 && sw == TRUE){
190
			if(peek == '|')gch();		/* eat up an extra '|' */
191
			return(0);
192
		}
193
		break;
194
 
195
case ';':
196
		if( brac == 0 ){
197
			Bputc(&fout, c);
198
			Bputc(&fout, '\n');
199
			return(1);
200
		}
201
		break;
202
 
203
case '{':
204
		brac++;
205
		savline=yyline;
206
		savfile=yyfile;
207
		break;
208
 
209
case '}':
210
		brac--;
211
		if( brac == 0 ){
212
			Bputc(&fout, c);
213
			Bputc(&fout, '\n');
214
			return(1);
215
		}
216
		break;
217
 
218
case '/':	/* look for comments */
219
		Bputc(&fout, c);
220
		c = gch();
221
		if( c != '*' ) goto swt;
222
 
223
		/* it really is a comment */
224
 
225
		Bputc(&fout, c);
226
		savline=yyline;
227
		savfile=yyfile;
228
		while( c=gch() ){
229
			if( c=='*' ){
230
				Bputc(&fout, c);
231
				if( (c=gch()) == '/' ) goto loop;
232
			}
233
			Bputc(&fout, c);
234
		}
235
		yyline=savline;
236
		yyfile=savfile;
237
		error( "EOF inside comment" );
238
 
239
case '\'':	/* character constant */
240
		mth = '\'';
241
		goto string;
242
 
243
case '"':	/* character string */
244
		mth = '"';
245
 
246
	string:
247
 
248
		Bputc(&fout, c);
249
		while( c=gch() ){
250
			if( c=='\\' ){
251
				Bputc(&fout, c);
252
				c=gch();
253
			}
254
			else if( c==mth ) goto loop;
255
			Bputc(&fout, c);
256
			if (c == '\n') {
257
				yyline--;
258
				error( "Non-terminated string or character constant");
259
			}
260
		}
261
		error( "EOF in string or character constant" );
262
 
263
case '\0':
264
		yyline = savline;
265
		yyfile = savfile;
266
		error("Action does not terminate");
267
default:
268
		break;		/* usual character */
269
		}
270
loop:
271
	if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
272
	Bputc(&fout, c);
273
	}
274
	error("Premature EOF");
275
	return(0);
276
}
277
 
278
int
279
gch(void){
280
	int c;
281
	prev = pres;
282
	c = pres = peek;
283
	peek = pushptr > pushc ? *--pushptr : Bgetc(fin);
284
	if(peek == Beof && sargc > 1){
285
		Bterm(fin);
286
		yyfile = sargv[fptr++];
287
		fin = Bopen(yyfile,OREAD);
288
		if(fin == 0)
289
			error("%s - cannot open file: %r",yyfile);
290
		peek = Bgetc(fin);
291
		sargc--;
292
		sargv++;
293
	}
294
	if(c == Beof) {
295
		eof = TRUE;
296
		Bterm(fin);
297
		fin = 0;
298
		return(0);
299
	}
300
	if(c == '\n')yyline++;
301
	return(c);
302
}
303
 
304
int
305
mn2(int a, int d, uintptr c)
306
{
307
	name[tptr] = a;
308
	left[tptr] = d;
309
	right[tptr] = c;
310
	parent[tptr] = 0;
311
	nullstr[tptr] = 0;
312
	switch(a){
313
	case RSTR:
314
		parent[d] = tptr;
315
		break;
316
	case BAR:
317
	case RNEWE:
318
		if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;
319
		parent[d] = parent[c] = tptr;
320
		break;
321
	case RCAT:
322
	case DIV:
323
		if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;
324
		parent[d] = parent[c] = tptr;
325
		break;
326
	case RSCON:
327
		parent[d] = tptr;
328
		nullstr[tptr] = nullstr[d];
329
		break;
330
# ifdef DEBUG
331
	default:
332
		warning("bad switch mn2 %d %d",a,d);
333
		break;
334
# endif
335
		}
336
	if(tptr > treesize)
337
		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
338
	return(tptr++);
339
}
340
 
341
int
342
mnp(int a, void *p)
343
{
344
	name[tptr] = a;
345
	left[tptr] = 0;
346
	parent[tptr] = 0;
347
	nullstr[tptr] = 0;
348
	ptr[tptr] = p;
349
	switch(a){
350
	case RCCL:
351
	case RNCCL:
352
		if(strlen(p) == 0) nullstr[tptr] = TRUE;
353
		break;
354
	default:
355
		error("bad switch mnp %d %P", a, p);
356
		break;
357
	}
358
	if(tptr > treesize)
359
		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
360
	return(tptr++);
361
}
362
 
363
int
364
mn1(int a, int d)
365
{
366
	name[tptr] = a;
367
	left[tptr] = d;
368
	parent[tptr] = 0;
369
	nullstr[tptr] = 0;
370
	switch(a){
371
	case STAR:
372
	case QUEST:
373
		nullstr[tptr] = TRUE;
374
		parent[d] = tptr;
375
		break;
376
	case PLUS:
377
	case CARAT:
378
		nullstr[tptr] = nullstr[d];
379
		parent[d] = tptr;
380
		break;
381
	case S2FINAL:
382
		nullstr[tptr] = TRUE;
383
		break;
384
# ifdef DEBUG
385
	case FINAL:
386
	case S1FINAL:
387
		break;
388
	default:
389
		warning("bad switch mn1 %d %d",a,d);
390
		break;
391
# endif
392
	}
393
	if(tptr > treesize)
394
		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
395
	return(tptr++);
396
}
397
 
398
int
399
mn0(int a)
400
{
401
	name[tptr] = a;
402
	parent[tptr] = 0;
403
	nullstr[tptr] = 0;
404
	if(a >= NCH) switch(a){
405
	case RNULLS: nullstr[tptr] = TRUE; break;
406
# ifdef DEBUG
407
	default:
408
		warning("bad switch mn0 %d",a);
409
		break;
410
# endif
411
	}
412
	if(tptr > treesize)
413
		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
414
	return(tptr++);
415
}
416
 
417
void
418
munputc(int p)
419
{
420
	*pushptr++ = peek;		/* watch out for this */
421
	peek = p;
422
	if(pushptr >= pushc+TOKENSIZE)
423
		error("Too many characters pushed");
424
}
425
 
426
void
427
munputs(uchar *p)
428
{
429
	int i,j;
430
	*pushptr++ = peek;
431
	peek = p[0];
432
	i = strlen((char*)p);
433
	for(j = i-1; j>=1; j--)
434
		*pushptr++ = p[j];
435
	if(pushptr >= pushc+TOKENSIZE)
436
		error("Too many characters pushed");
437
}
438
 
439
int
440
dupl(int n)
441
{
442
	/* duplicate the subtree whose root is n, return ptr to it */
443
	int i;
444
 
445
	i = name[n];
446
	if(i < NCH) return(mn0(i));
447
	switch(i){
448
	case RNULLS:
449
		return(mn0(i));
450
	case RCCL: case RNCCL:
451
		return(mnp(i,ptr[n]));
452
	case FINAL: case S1FINAL: case S2FINAL:
453
		return(mn1(i,left[n]));
454
	case STAR: case QUEST: case PLUS: case CARAT:
455
		return(mn1(i,dupl(left[n])));
456
	case RSTR: case RSCON:
457
		return(mn2(i,dupl(left[n]),right[n]));
458
	case BAR: case RNEWE: case RCAT: case DIV:
459
		return(mn2(i,dupl(left[n]),dupl(right[n])));
460
# ifdef DEBUG
461
	default:
462
		warning("bad switch dupl %d",n);
463
# endif
464
	}
465
	return(0);
466
}
467
 
468
# ifdef DEBUG
469
void
470
allprint(int c)
471
{
472
	if(c < 0)
473
		c += 256;	/* signed char */
474
	switch(c){
475
		case 014:
476
			print("\\f");
477
			charc++;
478
			break;
479
		case '\n':
480
			print("\\n");
481
			charc++;
482
			break;
483
		case '\t':
484
			print("\\t");
485
			charc++;
486
			break;
487
		case '\b':
488
			print("\\b");
489
			charc++;
490
			break;
491
		case ' ':
492
			print("\\\bb");
493
			break;
494
		default:
495
			if(!isprint(c)){
496
				print("\\%-3o",c);
497
				charc += 3;
498
			} else 
499
				print("%c", c);
500
			break;
501
	}
502
	charc++;
503
}
504
 
505
void
506
strpt(uchar *s)
507
{
508
	charc = 0;
509
	while(*s){
510
		allprint(*s++);
511
		if(charc > LINESIZE){
512
			charc = 0;
513
			print("\n\t");
514
		}
515
	}
516
}
517
 
518
void
519
sect1dump(void)
520
{
521
	int i;
522
 
523
	print("Sect 1:\n");
524
	if(def[0]){
525
		print("str	trans\n");
526
		i = -1;
527
		while(def[++i])
528
			print("%s\t%s\n",def[i],subs[i]);
529
	}
530
	if(sname[0]){
531
		print("start names\n");
532
		i = -1;
533
		while(sname[++i])
534
			print("%s\n",sname[i]);
535
	}
536
}
537
 
538
void
539
sect2dump(void)
540
{
541
	print("Sect 2:\n");
542
	treedump();
543
}
544
 
545
void
546
treedump(void)
547
{
548
	int t;
549
	uchar *p;
550
	print("treedump %d nodes:\n",tptr);
551
	for(t=0;t<tptr;t++){
552
		print("%4d ",t);
553
		parent[t] ? print("p=%4d",parent[t]) : print("      ");
554
		print("  ");
555
		if(name[t] < NCH)
556
				allprint(name[t]);
557
		else switch(name[t]){
558
			case RSTR:
559
				print("%d ",left[t]);
560
				allprint(right[t]);
561
				break;
562
			case RCCL:
563
				print("ccl ");
564
				allprint(ptr[t]);
565
				break;
566
			case RNCCL:
567
				print("nccl ");
568
				allprint(ptr[t]);
569
				break;
570
			case DIV:
571
				print("/ %d %d",left[t],right[t]);
572
				break;
573
			case BAR:
574
				print("| %d %d",left[t],right[t]);
575
				break;
576
			case RCAT:
577
				print("cat %d %d",left[t],right[t]);
578
				break;
579
			case PLUS:
580
				print("+ %d",left[t]);
581
				break;
582
			case STAR:
583
				print("* %d",left[t]);
584
				break;
585
			case CARAT:
586
				print("^ %d",left[t]);
587
				break;
588
			case QUEST:
589
				print("? %d",left[t]);
590
				break;
591
			case RNULLS:
592
				print("nullstring");
593
				break;
594
			case FINAL:
595
				print("final %d",left[t]);
596
				break;
597
			case S1FINAL:
598
				print("s1final %d",left[t]);	
599
				break;
600
			case S2FINAL:
601
				print("s2final %d",left[t]);
602
				break;
603
			case RNEWE:
604
				print("new %d %d",left[t],right[t]);
605
				break;
606
			case RSCON:
607
				p = (uchar *)right[t];
608
				print("start %s",sname[*p++-1]);
609
				while(*p)
610
					print(", %s",sname[*p++-1]);
611
				print(" %d",left[t]);
612
				break;
613
			default:
614
				print("unknown %d %d %d",name[t],left[t],right[t]);
615
				break;
616
		}
617
		if(nullstr[t])print("\t(null poss.)");
618
		print("\n");
619
	}
620
}
621
# endif