home *** CD-ROM | disk | FTP | other *** search
- /* SC A Spreadsheet Calculator
- * Command and expression parser
- *
- * original by James Gosling, September 1982
- * modified by Mark Weiser and Bruce Israel,
- * University of Maryland
- *
- * more mods Robert Bond 12/86
- *
- * More mods by Alan Silverstein, 3/88, see list of changes.
- *
- * $Revision: 6.21 $
- */
-
-
-
- %{
- #include <curses.h>
- #include "sc.h"
-
- #define ENULL (struct enode *)0
- %}
-
- %union {
- int ival;
- double fval;
- struct ent_ptr ent;
- struct enode *enode;
- char *sval;
- struct range_s rval;
- }
-
- %type <ent> var
- %type <fval> num
- %type <rval> range
- %type <rval> var_or_range
- %type <sval> strarg
- %type <enode> e term expr_list
- %token <sval> STRING
- %token <ival> NUMBER
- %token <fval> FNUMBER
- %token <rval> RANGE
- %token <rval> VAR
- %token <sval> SCWORD
- %token <ival> COL
- %token S_FORMAT
- %token S_FMT
- %token S_LABEL
- %token S_LEFTSTRING
- %token S_RIGHTSTRING
- %token S_GET
- %token S_PUT
- %token S_MERGE
- %token S_LET
- %token S_WRITE
- %token S_TBL
- %token S_COPY
- %token S_SHOW
- %token S_ERASE
- %token S_FILL
- %token S_LOCK
- %token S_UNLOCK
- %token S_GOTO
- %token S_DEFINE
- %token S_UNDEFINE
- %token S_VALUE
- %token S_MDIR
- %token S_HIDE
- %token S_SET
-
- %token K_ERROR
- %token K_INVALID
- %token K_FIXED
- %token K_SUM
- %token K_PROD
- %token K_AVG
- %token K_STDDEV
- %token K_COUNT
- %token K_ABS
- %token K_ACOS
- %token K_ASIN
- %token K_ATAN
- %token K_ATAN2
- %token K_CEIL
- %token K_COS
- %token K_EXP
- %token K_FABS
- %token K_FLOOR
- %token K_HYPOT
- %token K_LN
- %token K_LOG
- %token K_PI
- %token K_POW
- %token K_SIN
- %token K_SQRT
- %token K_TAN
- %token K_DTR
- %token K_RTD
- %token K_MAX
- %token K_MIN
- %token K_RND
- %token K_ROUND
- %token K_IF
-
- %token K_PV
- %token K_FV
- %token K_PMT
-
- %token K_HOUR
- %token K_MINUTE
- %token K_SECOND
- %token K_MONTH
- %token K_DAY
- %token K_YEAR
- %token K_NOW
- %token K_DATE
- %token K_DTS
- %token K_TTS
- %token K_FMT
- %token K_SUBSTR
- %token K_UPPER
- %token K_LOWER
- %token K_CAPITAL
- %token K_STON
- %token K_EQS
- %token K_EXT
- %token K_NVAL
- %token K_SVAL
- %token K_LOOKUP
- %token K_HLOOKUP
- %token K_VLOOKUP
- %token K_INDEX
- %token K_STINDEX
- %token K_AUTO
- %token K_AUTOCALC
- %token K_BYROWS
- %token K_BYCOLS
- %token K_ITERATIONS
- %token K_NUMERIC
- %token K_PRESCALE
- %token K_EXTFUN
- %token K_CELLCUR
- %token K_TOPROW
- %token K_TBLSTYLE
- %token K_TBL
- %token K_LATEX
- %token K_SLATEX
- %token K_TEX
- %token K_FRAME
- %token K_RNDINFINITY
- %token K_MYROW
- %token K_MYCOL
- %token K_COLTOA
- %token K_CRACTION
- %token K_CRROW
- %token K_CRCOL
- %token K_ROWLIMIT
- %token K_COLLIMIT
- %token K_NUMITER
-
- %left '?' ':'
- %left '|'
- %left '&'
- %nonassoc '<' '=' '>' '!'
- %left '+' '-' '#'
- %left '*' '/' '%'
- %left '^'
-
- %%
- command: S_LET var_or_range '=' e
- { let($2.left.vp, $4); }
- | S_LABEL var_or_range '=' e
- { slet($2.left.vp, $4, 0); }
- | S_LEFTSTRING var_or_range '=' e
- { slet($2.left.vp, $4, -1); }
- | S_RIGHTSTRING var_or_range '=' e
- { slet($2.left.vp, $4, 1); }
- | S_FORMAT COL ':' COL NUMBER NUMBER NUMBER
- { doformat($2,$4,$5,$6,$7); }
- | S_FORMAT COL NUMBER NUMBER NUMBER
- { doformat($2,$2,$3,$4,$5); }
- | S_FORMAT COL ':' COL NUMBER NUMBER
- { doformat($2,$4,$5,$6, REFMTFIX); }
- | S_FORMAT COL NUMBER NUMBER
- { doformat($2,$2,$3,$4, REFMTFIX); }
- | S_GET strarg { /* This tmp hack is because readfile
- * recurses back through yyparse. */
- char *tmp;
- tmp = $2;
- readfile (tmp, 1);
- scxfree(tmp);
- }
- | S_MERGE strarg {
- char *tmp;
- tmp = $2;
- readfile (tmp, 0);
- scxfree(tmp);
- }
- | S_MDIR strarg
- { if (mdir) scxfree(mdir); mdir = $2; }
- | S_PUT strarg range
- { (void) writefile($2, ($3.left.vp)->row,
- ($3.left.vp)->col, ($3.right.vp)->row,
- ($3.right.vp)->col);
- scxfree($2); }
- | S_PUT strarg
- { (void) writefile ($2, 0, 0, maxrow, maxcol);
- scxfree($2); }
- | S_WRITE strarg range { (void) printfile($2, ($3.left.vp)->row,
- ($3.left.vp)->col, ($3.right.vp)->row,
- ($3.right.vp)->col);
- scxfree($2); }
- | S_WRITE strarg { (void) printfile ($2, 0, 0, maxrow, maxcol);
- scxfree($2); }
- | S_TBL strarg range { (void) tblprintfile($2, ($3.left.vp)->row,
- ($3.left.vp)->col, ($3.right.vp)->row,
- ($3.right.vp)->col);
- scxfree($2); }
- | S_TBL strarg { (void)tblprintfile ($2, 0, 0, maxrow, maxcol);
- scxfree($2); }
- | S_SHOW COL ':' COL
- { showcol( $2, $4); }
- | S_SHOW NUMBER ':' NUMBER
- { showrow( $2, $4); }
- | S_HIDE COL
- { hide_col( $2 ); }
- | S_HIDE NUMBER
- { hide_row( $2 ); }
- | S_COPY range var_or_range
- { copy($2.left.vp,$2.right.vp,
- $3.left.vp,$3.right.vp); }
- | S_ERASE
- { eraser(lookat(showsr, showsc),
- lookat(currow, curcol)); }
- | S_ERASE var_or_range
- { eraser($2.left.vp, $2.right.vp); }
- | S_VALUE { valueize_area(showsr, showsc, currow, curcol);
- modflg++; }
- | S_VALUE var_or_range { valueize_area(($2.left.vp)->row,
- ($2.left.vp)->col,
- ($2.right.vp)->row,
- ($2.right.vp)->col); modflg++; }
- | S_FILL num num { fill(lookat(showsr, showsc),
- lookat(currow, curcol), $2, $3); }
- | S_FILL var_or_range num num
- { fill($2.left.vp, $2.right.vp, $3, $4); }
- | S_FMT var_or_range STRING
- { format_cell($2.left.vp, $2.right.vp, $3); }
- | S_LOCK
- { lock_cells(lookat(showsr, showsc),
- lookat(currow, curcol)); }
- | S_LOCK var_or_range
- { lock_cells($2.left.vp, $2.right.vp); }
- | S_UNLOCK
- { unlock_cells(lookat(showsr, showsc),
- lookat(currow, curcol)); }
- | S_UNLOCK var_or_range
- { unlock_cells($2.left.vp, $2.right.vp); }
- | S_GOTO var_or_range {moveto($2.left.vp->row, $2.left.vp->col);}
- | S_GOTO num { num_search($2, 0); }
- | S_GOTO errlist
- | S_GOTO STRING { str_search($2); }
- | S_GOTO { go_last(); }
- | S_DEFINE strarg { struct ent_ptr arg1, arg2;
- arg1.vp = lookat(showsr, showsc);
- arg1.vf = 0;
- arg2.vp = lookat(currow, curcol);
- arg2.vf = 0;
- if (arg1.vp == arg2.vp)
- add_range($2, arg2, arg2, 0);
- else
- add_range($2, arg1, arg2, 1); }
-
- | S_DEFINE strarg range { add_range($2, $3.left, $3.right, 1); }
- | S_DEFINE strarg var { add_range($2, $3, $3, 0); }
- | S_UNDEFINE var_or_range { del_range($2.left.vp, $2.right.vp); }
- | S_SET setlist
- | /* nothing */
- | error;
-
- term: var { $$ = new_var(O_VAR, $1); }
- | K_FIXED term { $$ = new ('f', ENULL, $2); }
- | '@' K_SUM '(' var_or_range ')'
- { $$ = new_range(REDUCE | '+', $4); }
- | '@' K_PROD '(' var_or_range ')'
- { $$ = new_range (REDUCE | '*', $4); }
- | '@' K_AVG '(' var_or_range ')'
- { $$ = new_range (REDUCE | 'a', $4); }
- | '@' K_STDDEV '(' var_or_range ')'
- { $$ = new_range (REDUCE | 's', $4); }
- | '@' K_COUNT '(' var_or_range ')'
- { $$ = new_range (REDUCE | 'c', $4); }
- | '@' K_MAX '(' var_or_range ')'
- { $$ = new_range (REDUCE | MAX, $4); }
- | '@' K_MAX '(' e ',' expr_list ')'
- { $$ = new(LMAX, $6, $4); }
- | '@' K_MIN '(' var_or_range ')'
- { $$ = new_range (REDUCE | MIN, $4); }
- | '@' K_MIN '(' e ',' expr_list ')'
- { $$ = new(LMIN, $6, $4); }
- | '@' K_ABS '(' e ')' { $$ = new(ABS, ENULL, $4); }
- | '@' K_ACOS '(' e ')' { $$ = new(ACOS, ENULL, $4); }
- | '@' K_ASIN '(' e ')' { $$ = new(ASIN, ENULL, $4); }
- | '@' K_ATAN '(' e ')' { $$ = new(ATAN, ENULL, $4); }
- | '@' K_ATAN2 '(' e ',' e ')' { $$ = new(ATAN2, $4, $6); }
- | '@' K_CEIL '(' e ')' { $$ = new(CEIL, ENULL, $4); }
- | '@' K_COS '(' e ')' { $$ = new(COS, ENULL, $4); }
- | '@' K_EXP '(' e ')' { $$ = new(EXP, ENULL, $4); }
- | '@' K_FABS '(' e ')' { $$ = new(FABS, ENULL, $4); }
- | '@' K_FLOOR '(' e ')' { $$ = new(FLOOR, ENULL, $4); }
- | '@' K_HYPOT '(' e ',' e ')' { $$ = new(HYPOT, $4, $6); }
- | '@' K_LN '(' e ')' { $$ = new(LOG, ENULL, $4); }
- | '@' K_LOG '(' e ')' { $$ = new(LOG10, ENULL, $4); }
- | '@' K_POW '(' e ',' e ')' { $$ = new(POW, $4, $6); }
- | '@' K_SIN '(' e ')' { $$ = new(SIN, ENULL, $4); }
- | '@' K_SQRT '(' e ')' { $$ = new(SQRT, ENULL, $4); }
- | '@' K_TAN '(' e ')' { $$ = new(TAN, ENULL, $4); }
- | '@' K_DTR '(' e ')' { $$ = new(DTR, ENULL, $4); }
- | '@' K_RTD '(' e ')' { $$ = new(RTD, ENULL, $4); }
- | '@' K_RND '(' e ')' { $$ = new(RND, ENULL, $4); }
- | '@' K_ROUND '(' e ',' e ')' { $$ = new(ROUND, $4, $6); }
- | '@' K_IF '(' e ',' e ',' e ')' { $$ = new(IF, $4,new(',',$6,$8)); }
-
- | '@' K_PV '(' e ',' e ',' e ')' { $$ = new(PV, $4,new(':',$6,$8)); }
- | '@' K_FV '(' e ',' e ',' e ')' { $$ = new(FV, $4,new(':',$6,$8)); }
- | '@' K_PMT '(' e ',' e ',' e ')' { $$ = new(PMT, $4,new(':',$6,$8)); }
-
- | '@' K_HOUR '(' e ')' { $$ = new(HOUR,ENULL, $4); }
- | '@' K_MINUTE '(' e ')' { $$ = new(MINUTE,ENULL, $4); }
- | '@' K_SECOND '(' e ')' { $$ = new(SECOND,ENULL, $4); }
- | '@' K_MONTH '(' e ')' { $$ = new(MONTH,ENULL,$4); }
- | '@' K_DAY '(' e ')' { $$ = new(DAY, ENULL, $4); }
- | '@' K_YEAR '(' e ')' { $$ = new(YEAR, ENULL, $4); }
- | '@' K_NOW { $$ = new(NOW, ENULL, ENULL);}
- | '@' K_DTS '(' e ',' e ',' e ')'
- { $$ = new(DTS, $4, new(',', $6, $8));}
- | '@' K_TTS '(' e ',' e ',' e ')'
- { $$ = new(TTS, $4, new(',', $6, $8));}
- | '@' K_STON '(' e ')' { $$ = new(STON, ENULL, $4); }
- | '@' K_EQS '(' e ',' e ')' { $$ = new (EQS, $4, $6); }
- | '@' K_DATE '(' e ')' { $$ = new(DATE, ENULL, $4); }
- | '@' K_FMT '(' e ',' e ')' { $$ = new(FMT, $4, $6); }
- | '@' K_UPPER '(' e ')' { $$ = new(UPPER, ENULL, $4); }
- | '@' K_LOWER '(' e ')' { $$ = new(LOWER, ENULL, $4); }
- | '@' K_CAPITAL '(' e ')' { $$ = new(CAPITAL, ENULL, $4); }
- | '@' K_INDEX '(' e ',' var_or_range ')'
- { $$ = new(INDEX, $4, new_range(REDUCE | INDEX, $6)); }
- | '@' K_LOOKUP '(' e ',' var_or_range ')'
- { $$ = new(LOOKUP, $4, new_range(REDUCE | LOOKUP, $6)); }
- | '@' K_HLOOKUP '(' e ',' var_or_range ',' e ')'
- { $$ = new(HLOOKUP, new(',', $4, $8),
- new_range(REDUCE | HLOOKUP, $6)); }
- | '@' K_VLOOKUP '(' e ',' var_or_range ',' e ')'
- { $$ = new(VLOOKUP, new(',', $4, $8),
- new_range(REDUCE | VLOOKUP, $6)); }
- | '@' K_STINDEX '(' e ',' var_or_range ')'
- { $$ = new(STINDEX, $4, new_range(REDUCE | STINDEX, $6)); }
- | '@' K_EXT '(' e ',' e ')' { $$ = new(EXT, $4, $6); }
- | '@' K_NVAL '(' e ',' e ')' { $$ = new(NVAL, $4, $6); }
- | '@' K_SVAL '(' e ',' e ')' { $$ = new(SVAL, $4, $6); }
- | '@' K_SUBSTR '(' e ',' e ',' e ')'
- { $$ = new(SUBSTR, $4, new(',', $6, $8)); }
- | '(' e ')' { $$ = $2; }
- | '+' term { $$ = $2; }
- | '-' term { $$ = new ('m', ENULL, $2); }
- | NUMBER { $$ = new_const(O_CONST, (double) $1); }
- | FNUMBER { $$ = new_const(O_CONST, $1); }
- | NUMBER '_' NUMBER '_' NUMBER
- { $$ = new_const(O_CONST, convert_date($1,$3,$5)); }
- | K_PI { $$ = new_const(O_CONST, (double)3.14159265358979323846); }
- | '@' K_PI { $$ = new_const(O_CONST, (double)3.14159265358979323846); }
- | STRING { $$ = new_str($1); }
- | '~' term { $$ = new ('~', ENULL, $2); }
- | '!' term { $$ = new ('~', ENULL, $2); }
- | '@' K_MYROW { $$ = new(MYROW, ENULL, ENULL);}
- | '@' K_MYCOL { $$ = new(MYCOL, ENULL, ENULL);}
- | '@' K_COLTOA '(' e ')' { $$ = new(COLTOA, ENULL, $4);}
- | '@' K_NUMITER { $$ = new(NUMITER, ENULL, ENULL);}
- ;
-
- /* expressions */
- e: e '+' e { $$ = new ('+', $1, $3); }
- | e '-' e { $$ = new ('-', $1, $3); }
- | e '*' e { $$ = new ('*', $1, $3); }
- | e '/' e { $$ = new ('/', $1, $3); }
- | e '%' e { $$ = new ('%', $1, $3); }
- | e '^' e { $$ = new ('^', $1, $3); }
- | term
- | e '?' e ':' e { $$ = new ('?', $1, new(':', $3, $5)); }
- | e '<' e { $$ = new ('<', $1, $3); }
- | e '=' e { $$ = new ('=', $1, $3); }
- | e '>' e { $$ = new ('>', $1, $3); }
- | e '&' e { $$ = new ('&', $1, $3); }
- | e '|' e { $$ = new ('|', $1, $3); }
- | e '<' '=' e { $$ = new ('~', ENULL, new ('>', $1, $4)); }
- | e '!' '=' e { $$ = new ('~', ENULL, new ('=', $1, $4)); }
- | e '<' '>' e { $$ = new ('~', ENULL, new ('=', $1, $4)); }
- | e '>' '=' e { $$ = new ('~', ENULL, new ('<', $1, $4)); }
- | e '#' e { $$ = new ('#', $1, $3); }
- ;
-
- expr_list: e { $$ = new(ELIST, ENULL, $1); }
- | expr_list ',' e { $$ = new(ELIST, $1, $3); }
- ;
-
- range: var ':' var { $$.left = $1; $$.right = $3; }
- | RANGE { $$ = $1; }
- ;
-
- var: COL NUMBER { $$.vp = lookat($2 , $1); $$.vf = 0; }
- | '$' COL NUMBER { $$.vp = lookat($3 , $2);
- $$.vf = FIX_COL; }
- | COL '$' NUMBER { $$.vp = lookat($3 , $1);
- $$.vf = FIX_ROW; }
- | '$' COL '$' NUMBER { $$.vp = lookat($4 , $2);
- $$.vf = FIX_ROW | FIX_COL; }
- | VAR { $$ = $1.left; }
- ;
-
- var_or_range: range { $$ = $1; }
- | var { $$.left = $1; $$.right = $1; }
- ;
-
- num: NUMBER { $$ = (double) $1; }
- | FNUMBER { $$ = $1; }
- | '-' num { $$ = -$2; }
- | '+' num { $$ = $2; }
- ;
-
- strarg: STRING { $$ = $1; }
- | var {
- char *s, *s1;
- s1 = $1.vp->label;
- if (!s1)
- s1 = "NULL_STRING";
- s = scxmalloc((unsigned)strlen(s1)+1);
- (void) strcpy(s, s1);
- $$ = s;
- }
- ;
-
- /* allows >=1 'setitem's to be listed in the same 'set' command */
- setlist :
- | setlist setitem
- ;
-
- /* things that you can 'set' */
- setitem : K_AUTO { setauto(1); }
- | K_AUTOCALC { setauto(1); }
- | '~' K_AUTO { setauto(0); }
- | '~' K_AUTOCALC { setauto(0); }
- | '!' K_AUTO { setauto(0); }
- | '!' K_AUTOCALC { setauto(0); }
- | K_BYCOLS { setorder(BYCOLS); }
- | K_BYROWS { setorder(BYROWS); }
- | K_NUMERIC { numeric = 1; }
- | '!' K_NUMERIC { numeric = 0; }
- | K_PRESCALE { prescale = 0.01; }
- | '!' K_PRESCALE { prescale = 1.0; }
- | K_EXTFUN { extfunc = 1; }
- | '!' K_EXTFUN { extfunc = 0; }
- | K_CELLCUR { showcell = 1; }
- | '!' K_CELLCUR { showcell = 0; }
- | K_TOPROW { showtop = 1; }
- | '!' K_TOPROW { showtop = 0; }
- | K_ITERATIONS '=' NUMBER { setiterations($3); }
- | K_TBLSTYLE '=' NUMBER { tbl_style = $3; }
- | K_TBLSTYLE '=' K_TBL { tbl_style = TBL; }
- | K_TBLSTYLE '=' K_LATEX { tbl_style = LATEX; }
- | K_TBLSTYLE '=' K_SLATEX { tbl_style = SLATEX; }
- | K_TBLSTYLE '=' K_TEX { tbl_style = TEX; }
- | K_TBLSTYLE '=' K_FRAME { tbl_style = FRAME; }
- | K_RNDINFINITY { rndinfinity = 1; FullUpdate++; }
- | '!' K_RNDINFINITY { rndinfinity = 0; FullUpdate++; }
- | K_CRACTION '=' NUMBER { craction = $3; }
- | K_ROWLIMIT '=' NUMBER { rowlimit = $3; }
- | K_COLLIMIT '=' NUMBER { collimit = $3; }
- ;
-
- /* types of errors, to 'goto' */
- errlist : K_ERROR { num_search((double)0, CELLERROR); }
- | K_INVALID { num_search((double)0, CELLINVALID); }
- ;
-