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