|
|
1.1 root 1: %{
2: /*
3: * parse.y 1.7
4: *
5: * Parser Description File for Spreadsheet Program `vis'
6: *
7: * A. F. Gettier
8: * Bell Laboratories
9: * Update made 11/15/82 10:51:06
10: * Retrieved 11/15/82 13:22:37
11: */
12:
13: #include <stdio.h>
14: #include <math.h>
15: #include "curses.h"
16: #include "vis.h"
17:
18: extern struct qheader Fixup;
19:
20: int Inrow, Incol;
21: %}
22:
23: %start lines
24:
25: %union {
26: char *sval;
27: double dval;
28: int ival;
29: struct vdef vval;
30: struct node nval;
31: struct range rval;
32: struct colstat cval;
33: }
34:
35: %type <ival> amount direc
36: %type <nval> expr
37: %type <rval> range
38: %type <cval> colstat
39:
40: %left '+' '-'
41: %left '*' '/' '%'
42: %left EXPON
43: %left UMINUS
44:
45: %token PI ABS ACOS ASIN ATAN ATAN2 COS EXP GAMMA HYPOT
46: %token INT LOG POW SIN SQRT COL DUP DUPLICATE
47: %token EDIT POSITION REDRAW REFRESH REP REPLICATE ROW
48: %token SCALE SHIFT SLIDE SHELL SH WIDTH QUIT TERM LIST
49: %token ERROR ZERO THRU AT DEBUG VER UP DOWN LEFT RIGHT
50: %token HELP
51: %token <sval> STR LETTERS READ WRITE COPY
52: %token <dval> NUMBER
53: %token <ival> FUNC
54: %token <vval> AVARIABLE
55: %token <nval> VARIABLE
56:
57: %%
58:
59: lines : /* empty */
60: | lines line
61: ;
62: line : AVARIABLE '=' expr TERM
63: {
64: struct node *nt;
65: /*
66: * Get the Target Node
67: */
68: nt = getnode( $1.row, $1.col );
69: /*
70: * Assign the String
71: */
72: if ( nt->def != 0 )
73: free( nt->def );
74: nt->def = $1.tval;
75: /*
76: * Was the Old Value a String?
77: */
78: if ( nt->type == STRING ) {
79: free( nt->svalue );
80: nt->svalue = 0;
81: }
82: /*
83: * Do the assignment
84: */
85: switch ( $3.type ) {
86: case NUM:
87: if ( nt->type != NUM || nt->value != $3.value ) {
88: struct qheader *y;
89: struct node *x;
90: y = qcopy( &(nt->depend) );
91: while ( (x=qread( y ) ) != 0 )
92: qadd( &Fixup, x );
93: nt->value = $3.value;
94: free( (char *)y );
95: }
96: nt->type = $3.type;
97: break;
98:
99: case STRING:
100: nt->svalue = $3.svalue;
101: nt->type = $3.type;
102: break;
103: default:
104: nt->type = UNRES;
105: }
106: prnode( nt );
107: }
108: | COPY TERM
109: {
110: FILE *fp;
111: char *fn;
112: if ( $1 == 0 )
113: fn = getfn();
114: else
115: fn = $1;
116: if ( (fp=fopen( fn, "w" )) == 0 ) {
117: char errbuf[64];
118: (void)sprintf( errbuf, "Cannot open '%s'", fn );
119: yyerror( errbuf );
120: lexinit();
121: }
122: else {
123: move( LINES-2, 0 );
124: printw( "Copying Screen Image to File '%s'", fn );
125: clrtoeol();
126: refresh();
127: copyfile( fp );
128: (void)fclose( fp );
129: }
130: }
131: | DEBUG TERM
132: {
133: /*
134: yydebug = 1 - yydebug;
135: */
136: }
137: | DUPLICATE range AT VARIABLE TERM
138: {
139: duplicate( $2.fromrow, $2.fromcol, $2.torow, $2.tocol,
140: $4.row, $4.col );
141: }
142: | DUP range AT VARIABLE TERM
143: {
144: duplicate( $2.fromrow, $2.fromcol, $2.torow, $2.tocol,
145: $4.row, $4.col );
146: }
147: | EDIT TERM
148: {
149: editfile();
150: }
151: | HELP TERM
152: {
153: listhelp();
154: }
155: | LIST TERM
156: {
157: listfile();
158: }
159: | QUIT TERM
160: {
161: quit();
162: }
163: | READ TERM
164: {
165: FILE *fp;
166: char *fn;
167: if ( $1 == 0 )
168: fn = getfn();
169: else
170: fn = $1;
171: if ( (fp=fopen( fn, "r" )) == 0 ) {
172: char errbuf[64];
173: (void)sprintf( errbuf, "Cannot open '%s'", fn );
174: yyerror( errbuf );
175: lexinit();
176: }
177: else {
178: move( LINES-2, 0 );
179: printw( "Reading from File '%s'", fn );
180: clrtoeol();
181: refresh();
182: readfile( fp );
183: }
184: }
185: | REDRAW TERM
186: {
187: wrefresh( curscr );
188: }
189: | REFRESH TERM
190: {
191: wrefresh( curscr );
192: }
193: | REPLICATE VARIABLE AT range TERM
194: {
195: replicate( $2.row, $2.col, $4.fromrow, $4.fromcol, $4.torow,
196: $4.tocol );
197: }
198: | REP VARIABLE AT range TERM
199: {
200: replicate( $2.row, $2.col, $4.fromrow, $4.fromcol, $4.torow,
201: $4.tocol );
202: }
203: | SCALE colstat
204: {
205: if ( $2.colnum < 0 )
206: setscale( $2.number );
207: else
208: isetscale( $2.colnum, $2.number );
209: }
210: | SHIFT direc amount
211: {
212: switch( $2 ) {
213: case 1:
214: scrup( $3 );
215: break;
216: case 2:
217: scrdown( $3 );
218: break;
219: case 3:
220: scrleft( $3 );
221: break;
222: case 4:
223: scrright( $3 );
224: }
225: }
226: | SH TERM
227: {
228: move( LINES-1, 0 );
229: clrtoeol();
230: refresh();
231: resetty();
232: (void)system( "/bin/sh" );
233: noecho();
234: crmode();
235: wrefresh( curscr );
236: }
237: | SHELL TERM
238: {
239: move( LINES-1, 0 );
240: clrtoeol();
241: refresh();
242: resetty();
243: (void)system( "/bin/sh" );
244: noecho();
245: crmode();
246: wrefresh( curscr );
247: }
248: | VER TERM
249: {
250: yyerror("VIS 1.7 11/15/82");
251: }
252: | WIDTH colstat
253: {
254: if ( $2.colnum < 0 )
255: setwidth( $2.number );
256: else
257: isetwidth( $2.colnum, $2.number );
258: }
259: | WRITE TERM
260: {
261: FILE *fp;
262: char *fn;
263: if ( $1 == 0 )
264: fn = getfn();
265: else
266: fn = $1;
267: if ( (fp=fopen( fn, "w" )) == 0 ) {
268: char errbuf[64];
269: (void)sprintf( errbuf, "Cannot open '%s'", fn );
270: yyerror( errbuf );
271: lexinit();
272: }
273: else {
274: move( LINES-2, 0 );
275: printw( "Writing to File '%s'", fn );
276: clrtoeol();
277: refresh();
278:
279: dumpfile( fp );
280:
281: (void)fclose( fp );
282: }
283: }
284: | ZERO TERM
285: {
286: /*
287: * zero out the current definitions
288: */
289: zerodef();
290: zeroscreen();
291: }
292: | error TERM
293: ;
294: expr : '(' expr ')'
295: {
296: $$ = $2;
297: }
298: | expr '+' expr
299: {
300: $$ = mathop( &($1), &($3) );
301: if ( $$.type == NUM ) $$.value = $1.value + $3.value;
302: }
303: | expr '-' expr
304: {
305: $$ = mathop( &($1), &($3) );
306: if ( $$.type == NUM ) $$.value = $1.value - $3.value;
307: }
308: | expr '*' expr
309: {
310: $$ = mathop( &($1), &($3) );
311: if ( $$.type == NUM ) $$.value = $1.value * $3.value;
312: }
313: | expr '/' expr
314: {
315: $$ = mathop( &($1), &($3) );
316: if ( $$.type == NUM ) {
317: if ( $3.value == 0 ) $$.value = BIG;
318: else $$.value = $1.value / $3.value;
319: }
320: }
321: | expr EXPON expr
322: {
323: $$ = mathop( &($1), &($3) );
324: if ( $$.type == NUM ) $$.value = pow( $1.value, $3.value );
325: }
326: | '-' expr %prec UMINUS
327: {
328: $$ = $2;
329: $$.value = - $2.value;
330: }
331: | '+' expr %prec UMINUS
332: {
333: $$ = $2;
334: }
335: | FUNC '(' expr ')'
336: {
337: double xval;
338: $$ = mathop( &($3), &($3) );
339: if ( $$.type == NUM ) {
340: xval = $3.value;
341: switch( $1 ) {
342: case ABS:
343: if ( xval < 0 ) $$.value = -xval;
344: else $$.value = xval;
345: break;
346: case ACOS:
347: $$.value = acos( xval );
348: break;
349: case ASIN:
350: $$.value = asin( xval );
351: break;
352: case ATAN:
353: $$.value = atan( xval );
354: break;
355: case COS:
356: $$.value = cos( xval );
357: break;
358: case EXP:
359: $$.value = exp( xval );
360: break;
361: case GAMMA:
362: $$.value = gamma( xval );
363: break;
364: case INT:
365: $$.value = (double)((int)xval);
366: break;
367: case LOG:
368: $$.value = log( xval );
369: break;
370: case SIN:
371: $$.value = sin( xval );
372: break;
373: case SQRT:
374: $$.value = sqrt( xval );
375: break;
376: default:
377: lexinit();
378: unput( '\n' );
379: yyerror( "Incorrect Function Call" );
380: }
381: }
382: }
383: | FUNC '(' expr ',' expr ')'
384: {
385: double xval, yval;
386: $$ = mathop( &($3), &($5) );
387: if ( $$.type == NUM ) {
388: xval = $3.value;
389: yval = $5.value;
390: switch( $1 ) {
391: case ATAN2:
392: $$.value = atan2( xval, yval );
393: break;
394: case HYPOT:
395: $$.value = hypot( xval, yval );
396: break;
397: case POW:
398: $$.value = pow( xval, yval );
399: break;
400: default:
401: lexinit();
402: unput( '\n' );
403: yyerror( "Incorrect Function Call" );
404: }
405: }
406: }
407: | POSITION '[' expr ',' expr ']'
408: {
409: struct node *n;
410: $$ = mathop( &($3), &($5) );
411: if ( $$.type == NUM ) {
412: int i, j;
413: i = (int)$3.value-1;
414: j = (int)$5.value-1;
415: if ( i < 0 || j < 0 ) {
416: char bfr[128];
417: lexinit();
418: (void)sprintf( bfr,
419: "Illegal Request for Position[ %d, %d ]",
420: i+1, j+1 );
421: yyerror( bfr );
422: $$.type = UNDEF;
423: unput( '\n' );
424: }
425: else {
426: n = getnode( i, j );
427: prnode( n );
428: qadd( &(n->depend), getnode( Inrow, Incol ) );
429: $$ = *n;
430: if ( $$.type == STRING )
431: $$.svalue = copystr( $$.svalue );
432: $$.row = -1;
433: $$.col = -1;
434: }
435: }
436: else
437: $$.type = UNRES;
438: }
439: | COL
440: {
441: $$.svalue = 0;
442: $$.def = 0;
443: $$.type = NUM;
444: $$.value = (float)(Incol + 1);
445: $$.row = -1;
446: $$.col = -1;
447: }
448: | ROW
449: {
450: $$.svalue = 0;
451: $$.def = 0;
452: $$.type = NUM;
453: $$.value = (float)(Inrow+1);
454: $$.row = -1;
455: $$.col = -1;
456: }
457: | VARIABLE
458: {
459: struct node *x;
460: x = getnode( $1.row, $1.col );
461: $$ = *x;
462: /* If it is a string, patch it up */
463: if ( x->type == STRING ) {
464: $$.svalue = copystr( x->svalue );
465: $$.row = $$.col = (-1);
466: }
467: /* Mark The Screen That it is Undef */
468: if ( x->type == UNDEF ) prnode( x );
469: /* Set up the Dependency List */
470: (void)qadd( &(x->depend), getnode( Inrow, Incol ) );
471: }
472: | STR
473: {
474: $$.row = -1;
475: $$.col = -1;
476: $$.type = STRING;
477: $$.svalue = $1;
478: }
479: | NUMBER
480: {
481: $$.row = -1;
482: $$.col = -1;
483: $$.type = NUM;
484: $$.value = $1;
485: $$.svalue = 0;
486: $$.def = 0;
487: }
488: ;
489: range : VARIABLE THRU VARIABLE
490: {
491: $$.fromrow = $1.row;
492: $$.fromcol = $1.col;
493: $$.torow = $3.row;
494: $$.tocol = $3.col;
495: }
496: | VARIABLE
497: {
498: $$.fromrow = $$.torow = $1.row;
499: $$.fromcol = $$.tocol = $1.col;
500: }
501: ;
502: direc : UP
503: {
504: $$ = 1;
505: }
506: | DOWN
507: {
508: $$ = 2;
509: }
510: | LEFT
511: {
512: $$ = 3;
513: }
514: | RIGHT
515: {
516: $$ = 4;
517: }
518: ;
519: amount : TERM
520: {
521: $$ = 1;
522: }
523: | NUMBER TERM
524: {
525: $$ = (int)$1;
526: }
527: ;
528: colstat : NUMBER TERM
529: {
530: $$.colnum = -1;
531: $$.number = (int)$1;
532: }
533: | LETTERS NUMBER TERM
534: {
535: $$.colnum = colval( foldup( $1 ) );
536: $$.number = (int)$2;
537: free( $1 );
538: }
539: ;
540: %%
541:
542: char *
543: getfn()
544: {
545: static char chrbuf[64];
546: char *tbuf;
547: move( 22, 0 );
548: printw("Enter File Name: " );
549: refresh();
550:
551:
552: tbuf = chrbuf;
553: loop {
554: *tbuf = getch();
555: addch( *tbuf );
556: refresh();
557: if ( *(tbuf++) == '\n' ) break;
558: }
559: *(--tbuf) = '\0';
560:
561: return( chrbuf );
562: }
563:
564: colval( string )
565: char *string;
566: {
567: int i;
568: i = -1;
569: while ( *string != '\0' ) {
570: i = (i + 1) * 26 + *string - 'A';
571: string++;
572: }
573: return( i );
574: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.