xref: /original-bsd/contrib/sc/gram.y (revision f95533f0)
1 /*	SC	A Spreadsheet Calculator
2  *		Command and expression parser
3  *
4  *		original by James Gosling, September 1982
5  *		modified by Mark Weiser and Bruce Israel,
6  *			University of Maryland
7  *
8  * 		more mods Robert Bond 12/86
9  *
10  *		More mods by Alan Silverstein, 3/88, see list of changes.
11  *
12  *		$Revision: 6.8 $
13  */
14 
15 
16 
17 %{
18 #include <curses.h>
19 #include "sc.h"
20 
21 #define ENULL (struct enode *)0
22 
23 char *strcpy();
24 %}
25 
26 %union {
27     int ival;
28     double fval;
29     struct ent_ptr ent;
30     struct enode *enode;
31     char *sval;
32     struct range_s rval;
33 }
34 
35 %type <ent> var
36 %type <fval> num
37 %type <rval> range
38 %type <rval> var_or_range
39 %type <sval> strarg
40 %type <enode> e term expr_list
41 %token <sval> STRING
42 %token <ival> NUMBER
43 %token <fval> FNUMBER
44 %token <rval> RANGE
45 %token <rval> VAR
46 %token <sval> WORD
47 %token <ival> COL
48 %token S_FORMAT
49 %token S_LABEL
50 %token S_LEFTSTRING
51 %token S_RIGHTSTRING
52 %token S_GET
53 %token S_PUT
54 %token S_MERGE
55 %token S_LET
56 %token S_WRITE
57 %token S_TBL
58 %token S_COPY
59 %token S_SHOW
60 %token S_ERASE
61 %token S_FILL
62 %token S_GOTO
63 %token S_DEFINE
64 %token S_UNDEFINE
65 %token S_VALUE
66 %token S_MDIR
67 %token S_HIDE
68 %token S_SET
69 
70 %token K_FIXED
71 %token K_SUM
72 %token K_PROD
73 %token K_AVG
74 %token K_STDDEV
75 %token K_COUNT
76 %token K_ABS
77 %token K_ACOS
78 %token K_ASIN
79 %token K_ATAN
80 %token K_ATAN2
81 %token K_CEIL
82 %token K_COS
83 %token K_EXP
84 %token K_FABS
85 %token K_FLOOR
86 %token K_HYPOT
87 %token K_LN
88 %token K_LOG
89 %token K_PI
90 %token K_POW
91 %token K_SIN
92 %token K_SQRT
93 %token K_TAN
94 %token K_DTR
95 %token K_RTD
96 %token K_MAX
97 %token K_MIN
98 %token K_RND
99 %token K_ROUND
100 %token K_IF
101 
102 %token K_PV
103 %token K_FV
104 %token K_PMT
105 
106 %token K_HOUR
107 %token K_MINUTE
108 %token K_SECOND
109 %token K_MONTH
110 %token K_DAY
111 %token K_YEAR
112 %token K_NOW
113 %token K_DATE
114 %token K_DTS
115 %token K_TTS
116 %token K_FMT
117 %token K_SUBSTR
118 %token K_STON
119 %token K_EQS
120 %token K_EXT
121 %token K_NVAL
122 %token K_SVAL
123 %token K_LOOKUP
124 %token K_HLOOKUP
125 %token K_VLOOKUP
126 %token K_INDEX
127 %token K_STINDEX
128 %token K_AUTO
129 %token K_AUTOCALC
130 %token K_BYROWS
131 %token K_BYCOLS
132 %token K_BYGRAPH
133 %token K_ITERATIONS
134 %token K_NUMERIC
135 %token K_PRESCALE
136 %token K_EXTFUN
137 %token K_CELLCUR
138 %token K_TOPROW
139 %token K_TBLSTYLE
140 %token K_TBL
141 %token K_LATEX
142 %token K_TEX
143 
144 %left '?' ':'
145 %left '|'
146 %left '&'
147 %nonassoc '<' '=' '>' '!'
148 %left '+' '-' '#'
149 %left '*' '/' '%'
150 %left '^'
151 
152 %%
153 command:	S_LET var_or_range '=' e
154 				{ let($2.left.vp, $4); }
155 	|	S_LABEL var_or_range '=' e
156 				{ slet($2.left.vp, $4, 0); }
157 	|	S_LEFTSTRING var_or_range '=' e
158 				{ slet($2.left.vp, $4, -1); }
159 	|	S_RIGHTSTRING var_or_range '=' e
160 				{ slet($2.left.vp, $4, 1); }
161 	|	S_FORMAT COL ':' COL NUMBER NUMBER
162 				{ doformat($2,$4,$5,$6); }
163 	|	S_FORMAT COL NUMBER NUMBER
164 				{ doformat($2,$2,$3,$4); }
165 	|	S_GET strarg	{  /* This tmp hack is because readfile
166 				    * recurses back through yyparse. */
167 				  char *tmp;
168 				  tmp = $2;
169 				  readfile (tmp, 1);
170 				  xfree(tmp);
171 				}
172 	|	S_MERGE strarg	{
173 				  char *tmp;
174 				  tmp = $2;
175 				  readfile (tmp, 0);
176 				  xfree(tmp);
177 				}
178 	|	S_MDIR strarg
179 				{ if (mdir) xfree(mdir); mdir = $2; }
180 	|       S_PUT strarg range
181 				{ (void) writefile($2, ($3.left.vp)->row,
182 			 	($3.left.vp)->col, ($3.right.vp)->row,
183 			 	($3.right.vp)->col);
184 			 	xfree($2); }
185 	|	S_PUT strarg
186 				{ (void) writefile ($2, 0, 0, maxrow, maxcol);
187 			 	xfree($2); }
188 	|       S_WRITE strarg range { (void) printfile($2, ($3.left.vp)->row,
189 			 ($3.left.vp)->col, ($3.right.vp)->row,
190 			 ($3.right.vp)->col);
191 			 xfree($2); }
192 	|	S_WRITE strarg	{ (void) printfile ($2, 0, 0, maxrow, maxcol);
193 			 xfree($2); }
194 	|       S_TBL strarg range { (void) tblprintfile($2, ($3.left.vp)->row,
195 			 ($3.left.vp)->col, ($3.right.vp)->row,
196 			 ($3.right.vp)->col);
197 			 xfree($2); }
198 	|	S_TBL strarg	{ (void)tblprintfile ($2, 0, 0, maxrow, maxcol);
199 			 xfree($2); }
200 	|       S_SHOW COL ':' COL
201 					{ showcol( $2, $4); }
202 	|       S_SHOW NUMBER ':' NUMBER
203 					{ showrow( $2, $4); }
204  	|	S_HIDE COL
205  					{ hide_col( $2 ); }
206  	|	S_HIDE NUMBER
207  					{ hide_row( $2 ); }
208 	|	S_COPY range var_or_range
209 					{ copy($2.left.vp,$2.right.vp,
210 					$3.left.vp,$3.right.vp); }
211 	|	S_ERASE
212 					{ eraser(lookat(showsr, showsc),
213 				        lookat(currow, curcol)); }
214 	|	S_ERASE var_or_range
215 					{ eraser($2.left.vp, $2.right.vp); }
216 	|	S_VALUE       { valueize_area(showsr, showsc, currow, curcol);
217 				 modflg++; }
218 	|	S_VALUE var_or_range { valueize_area(($2.left.vp)->row,
219 				($2.left.vp)->col,
220 				($2.right.vp)->row,
221 				($2.right.vp)->col); modflg++; }
222 	|	S_FILL num num  { fill(lookat(showsr, showsc),
223 				      lookat(currow, curcol), $2, $3); }
224 	|	S_FILL var_or_range num num
225 				 { fill($2.left.vp, $2.right.vp, $3, $4); }
226 	|	S_GOTO var_or_range {moveto($2.left.vp->row, $2.left.vp->col);}
227 	|       S_GOTO num          {num_search($2);}
228 	|       S_GOTO STRING       {str_search($2);}
229 	|	S_GOTO              {go_last();}
230 	|	S_DEFINE strarg       { struct ent_ptr arg1, arg2;
231 					arg1.vp = lookat(showsr, showsc);
232 					arg1.vf = 0;
233 					arg2.vp = lookat(currow, curcol);
234 					arg2.vf = 0;
235 					add_range($2, arg1, arg2, 1); }
236 
237 	|	S_DEFINE strarg range { add_range($2, $3.left, $3.right, 1); }
238 	|	S_DEFINE strarg var   { add_range($2, $3, $3, 0); }
239 	|	S_UNDEFINE var_or_range { del_range($2.left.vp, $2.right.vp); }
240  	|	S_SET setlist
241 	|	/* nothing */
242 	|	error;
243 
244 term: 		var		{ $$ = new_var('v', $1); }
245 	|	K_FIXED term	{ $$ = new ('f', ENULL, $2); }
246 	|       '@' K_SUM '(' var_or_range ')'
247 				{ $$ = new_range(REDUCE | '+', $4); }
248 	|       '@' K_PROD '(' var_or_range ')'
249 				{ $$ = new_range (REDUCE | '*', $4); }
250 	|       '@' K_AVG '(' var_or_range ')'
251 				{ $$ = new_range (REDUCE | 'a', $4); }
252 	|       '@' K_STDDEV '(' var_or_range ')'
253 				{ $$ = new_range (REDUCE | 's', $4); }
254 	|       '@' K_COUNT '(' var_or_range ')'
255 				{ $$ = new_range (REDUCE | 'c', $4); }
256 	|       '@' K_MAX '(' var_or_range ')'
257 				{ $$ = new_range (REDUCE | MAX, $4); }
258 	|	'@' K_MAX '(' e ',' expr_list ')'
259 				{ $$ = new(LMAX, $6, $4); }
260 	|       '@' K_MIN '(' var_or_range ')'
261 				{ $$ = new_range (REDUCE | MIN, $4); }
262 	|	'@' K_MIN '(' e ',' expr_list ')'
263 				{ $$ = new(LMIN, $6, $4); }
264 	| '@' K_ABS '(' e ')'	 { $$ = new(ABS, ENULL, $4); }
265 	| '@' K_ACOS '(' e ')'	 { $$ = new(ACOS, ENULL, $4); }
266 	| '@' K_ASIN '(' e ')'	 { $$ = new(ASIN, ENULL, $4); }
267 	| '@' K_ATAN '(' e ')'	 { $$ = new(ATAN, ENULL, $4); }
268 	| '@' K_ATAN2 '(' e ',' e ')' { $$ = new(ATAN2, $4, $6); }
269 	| '@' K_CEIL '(' e ')'	 { $$ = new(CEIL, ENULL, $4); }
270 	| '@' K_COS '(' e ')'	 { $$ = new(COS, ENULL, $4); }
271 	| '@' K_EXP '(' e ')'	 { $$ = new(EXP, ENULL, $4); }
272 	| '@' K_FABS '(' e ')'	 { $$ = new(FABS, ENULL, $4); }
273 	| '@' K_FLOOR '(' e ')'	 { $$ = new(FLOOR, ENULL, $4); }
274 	| '@' K_HYPOT '(' e ',' e ')'	{ $$ = new(HYPOT, $4, $6); }
275 	| '@' K_LN '(' e ')'	 { $$ = new(LOG, ENULL, $4); }
276 	| '@' K_LOG '(' e ')'	 { $$ = new(LOG10, ENULL, $4); }
277 	| '@' K_POW '(' e ',' e ')'	{ $$ = new(POW, $4, $6); }
278 	| '@' K_SIN '(' e ')'	 { $$ = new(SIN, ENULL, $4); }
279 	| '@' K_SQRT '(' e ')'	 { $$ = new(SQRT, ENULL, $4); }
280 	| '@' K_TAN '(' e ')'	 { $$ = new(TAN, ENULL, $4); }
281 	| '@' K_DTR '(' e ')'	 { $$ = new(DTR, ENULL, $4); }
282 	| '@' K_RTD '(' e ')'	 { $$ = new(RTD, ENULL, $4); }
283 	| '@' K_RND '(' e ')'	 { $$ = new(RND, ENULL, $4); }
284 	| '@' K_ROUND '(' e ',' e ')'	 { $$ = new(ROUND, $4, $6); }
285 	| '@' K_IF  '(' e ',' e ',' e ')' { $$ = new(IF,  $4,new(',',$6,$8)); }
286 
287 	| '@' K_PV  '(' e ',' e ',' e ')' { $$ = new(PV,  $4,new(':',$6,$8)); }
288  	| '@' K_FV  '(' e ',' e ',' e ')' { $$ = new(FV,  $4,new(':',$6,$8)); }
289  	| '@' K_PMT '(' e ',' e ',' e ')' { $$ = new(PMT, $4,new(':',$6,$8)); }
290 
291 	| '@' K_HOUR '(' e ')' 	 { $$ = new(HOUR,ENULL, $4); }
292 	| '@' K_MINUTE '(' e ')' { $$ = new(MINUTE,ENULL, $4); }
293 	| '@' K_SECOND '(' e ')' { $$ = new(SECOND,ENULL, $4); }
294 	| '@' K_MONTH '(' e ')'	 { $$ = new(MONTH,ENULL,$4); }
295 	| '@' K_DAY '(' e ')'    { $$ = new(DAY, ENULL, $4); }
296 	| '@' K_YEAR '(' e ')'   { $$ = new(YEAR, ENULL, $4); }
297 	| '@' K_NOW              { $$ = new(NOW, ENULL, ENULL);}
298 	| '@' K_DTS '(' e ',' e ',' e ')'
299 		  		 { $$ = new(DTS, $4, new(',', $6, $8));}
300 	| '@' K_TTS '(' e ',' e ',' e ')'
301 		  		 { $$ = new(TTS, $4, new(',', $6, $8));}
302 	| '@' K_STON '(' e ')'   { $$ = new(STON, ENULL, $4); }
303 	| '@' K_EQS '(' e ',' e ')' { $$ = new (EQS, $4, $6); }
304 	| '@' K_DATE '(' e ')'	 { $$ = new(DATE, ENULL, $4); }
305 	| '@' K_FMT  '(' e ',' e ')' { $$ = new(FMT, $4, $6); }
306 	| '@' K_INDEX  '(' e ',' var_or_range ')'
307 		 { $$ = new(INDEX, $4, new_range(REDUCE | INDEX, $6)); }
308 	| '@' K_LOOKUP  '(' e ',' var_or_range ')'
309 		 { $$ = new(LOOKUP, $4, new_range(REDUCE | LOOKUP, $6)); }
310 	| '@' K_HLOOKUP  '(' e ',' var_or_range ',' e ')'
311 		 { $$ = new(HLOOKUP, new(',', $4, $8),
312 		    new_range(REDUCE | HLOOKUP, $6)); }
313 	| '@' K_VLOOKUP  '(' e ',' var_or_range ',' e ')'
314 		 { $$ = new(VLOOKUP, new(',', $4, $8),
315 		    new_range(REDUCE | VLOOKUP, $6)); }
316 	| '@' K_STINDEX  '(' e ',' var_or_range ')'
317 		 { $$ = new(STINDEX, $4, new_range(REDUCE | STINDEX, $6)); }
318 	| '@' K_EXT  '(' e ',' e ')' { $$ = new(EXT, $4, $6); }
319 	| '@' K_NVAL '(' e ',' e ')' { $$ = new(NVAL, $4, $6); }
320 	| '@' K_SVAL '(' e ',' e ')' { $$ = new(SVAL, $4, $6); }
321 	| '@' K_SUBSTR '(' e ',' e ',' e ')'
322 				 { $$ = new(SUBSTR, $4, new(',', $6, $8)); }
323 	|	'(' e ')'	 { $$ = $2; }
324 	|	'+' term	 { $$ = $2; }
325 	|	'-' term	 { $$ = new ('m', ENULL, $2); }
326 	|	NUMBER		 { $$ = new_const('k', (double) $1); }
327 	|	FNUMBER		 { $$ = new_const('k', $1); }
328 	|	K_PI	{ $$ = new_const('k', (double)3.14159265358979323846); }
329 	|	STRING	         { $$ = new_str($1); }
330 	|	'~' term	 { $$ = new ('~', ENULL, $2); }
331 	|	'!' term	 { $$ = new ('~', ENULL, $2); }
332 	;
333 
334 e:		e '+' e		{ $$ = new ('+', $1, $3); }
335 	|	e '-' e		{ $$ = new ('-', $1, $3); }
336 	|	e '*' e		{ $$ = new ('*', $1, $3); }
337 	|	e '/' e		{ $$ = new ('/', $1, $3); }
338 	|	e '%' e		{ $$ = new ('%', $1, $3); }
339 	|	e '^' e		{ $$ = new ('^', $1, $3); }
340 	|	term
341 	|	e '?' e ':' e	{ $$ = new ('?', $1, new(':', $3, $5)); }
342 	|	e '<' e		{ $$ = new ('<', $1, $3); }
343 	|	e '=' e		{ $$ = new ('=', $1, $3); }
344 	|	e '>' e		{ $$ = new ('>', $1, $3); }
345 	|	e '&' e		{ $$ = new ('&', $1, $3); }
346 	|	e '|' e		{ $$ = new ('|', $1, $3); }
347 	|	e '<' '=' e	{ $$ = new ('~', ENULL, new ('>', $1, $4)); }
348 	|	e '!' '=' e	{ $$ = new ('~', ENULL, new ('=', $1, $4)); }
349 	|	e '>' '=' e	{ $$ = new ('~', ENULL, new ('<', $1, $4)); }
350 	|	e '#' e		{ $$ = new ('#', $1, $3); }
351 	;
352 
353 expr_list:	e		{ $$ = new(ELIST, ENULL, $1); }
354 	|	expr_list ',' e	{ $$ = new(ELIST, $1, $3); }
355 	;
356 
357 range:		var ':' var	{ $$.left = $1; $$.right = $3; }
358 	| 	RANGE		{ $$ = $1; }
359 	;
360 
361 var:		COL NUMBER	{ $$.vp = lookat($2 , $1); $$.vf = 0;}
362 	|	'$' COL NUMBER	{ $$.vp = lookat($3 , $2);
363 					$$.vf = FIX_COL;}
364 	|	COL '$' NUMBER	{ $$.vp = lookat($3 , $1);
365 					$$.vf = FIX_ROW;}
366 	|	'$' COL '$' NUMBER { $$.vp = lookat($4 , $2);
367 					$$.vf = FIX_ROW | FIX_COL;}
368 	|	VAR		{ $$ = $1.left; }
369 	;
370 
371 var_or_range:	range		{ $$ = $1; }
372 	|	var		{ $$.left = $1; $$.right = $1; }
373 	;
374 
375 num:		NUMBER		{ $$ = (double) $1; }
376 	|	FNUMBER		{ $$ = $1; }
377 	|	'-' num		{ $$ = -$2; }
378 	|	'+' num		{ $$ = $2; }
379 	;
380 
381 strarg:		STRING		{ $$ = $1; }
382 	|	var		{
383 				    char *s, *s1;
384 				    s1 = $1.vp->label;
385 				    if (!s1)
386 					s1 = "NULL_STRING";
387 				    s = xmalloc((unsigned)strlen(s1)+1);
388 				    (void) strcpy(s, s1);
389 				    $$ = s;
390 				}
391   	;
392 
393 setlist :
394 	|	setlist setitem
395 	;
396 
397 setitem	:	K_AUTO		{ setauto(1); }
398 	|	K_AUTOCALC	{ setauto(1); }
399 	|	'~' K_AUTO	{ setauto(0); }
400 	|	'~' K_AUTOCALC	{ setauto(0); }
401 	|	'!' K_AUTO	{ setauto(0); }
402 	|	'!' K_AUTOCALC	{ setauto(0); }
403 	|	K_BYCOLS	{ setorder(BYCOLS); }
404 	|	K_BYROWS	{ setorder(BYROWS); }
405 	|	K_BYGRAPH	{ setorder(BYGRAPH); }
406 	|	K_NUMERIC	{ numeric = 1; }
407 	|	'!' K_NUMERIC	{ numeric = 0; }
408 	|	K_PRESCALE	{ prescale = 0.01; }
409 	|	'!' K_PRESCALE	{ prescale = 1.0; }
410 	|	K_EXTFUN	{ extfunc = 1; }
411 	|	'!' K_EXTFUN	{ extfunc = 0; }
412 	|	K_CELLCUR	{ showcell = 1; }
413 	|	'!' K_CELLCUR	{ showcell = 0; }
414 	|	K_TOPROW	{ showtop = 1; }
415 	|	'!' K_TOPROW	{ showtop = 0; }
416 	|	K_ITERATIONS '=' NUMBER	{ setiterations($3); }
417 	|	K_TBLSTYLE '=' NUMBER	{ tbl_style = $3; }
418 	|	K_TBLSTYLE '=' K_TBL	{ tbl_style = TBL; }
419 	|	K_TBLSTYLE '=' K_LATEX	{ tbl_style = LATEX; }
420 	|	K_TBLSTYLE '=' K_TEX	{ tbl_style = TEX; }
421   	;
422