new libsa version
[unix-history] / usr / src / contrib / sc / gram.y
CommitLineData
efc7f434
KB
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
23char *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%%
153command: 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
244term: 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
334e: 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
353expr_list: e { $$ = new(ELIST, ENULL, $1); }
354 | expr_list ',' e { $$ = new(ELIST, $1, $3); }
355 ;
356
357range: var ':' var { $$.left = $1; $$.right = $3; }
358 | RANGE { $$ = $1; }
359 ;
360
361var: 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
371var_or_range: range { $$ = $1; }
372 | var { $$.left = $1; $$.right = $1; }
373 ;
374
375num: NUMBER { $$ = (double) $1; }
376 | FNUMBER { $$ = $1; }
377 | '-' num { $$ = -$2; }
378 | '+' num { $$ = $2; }
379 ;
380
381strarg: 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
393setlist :
394 | setlist setitem
395 ;
396
397setitem : 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 ;