/* SC A Spreadsheet Calculator * Command and expression parser * * James Gosling, September 1982 * */ %{ #include "sc.h" %} %union { long ival; double fval; struct ent *ent; struct enode *enode; char *sval; } %type e term %type var %token STRING %token NUMBER %type row, col %token FNUMBER %token WORD %type reduce_op %token S_FORMAT %token S_LABEL %token S_LEFTSTRING %token S_RIGHTSTRING %token S_GET %token S_PUT %token S_LET %token S_WRITE %token K_FIXED %token K_R %token K_C %left '?' ':' %left '|' %left '&' %nonassoc '<' '=' '>' %left '+' '-' %left '*' '/' %% command: S_LET var '=' e { let ($2, $4); } | S_LABEL var '=' STRING { label ($2, $4, 0); } | S_LEFTSTRING var '=' STRING { label ($2, $4, -1); } | S_RIGHTSTRING var '=' STRING { label ($2, $4, 1); } | S_FORMAT NUMBER NUMBER NUMBER { fwidth[$2] = $3; FullUpdate++; precision[$2] = $4; } | S_GET STRING { readfile ($2); } | S_PUT STRING { writefile ($2); } | S_WRITE STRING { printfile ($2); } | /* nothing */ | error; row: K_R NUMBER { $$ = $2; }; col: K_C NUMBER { $$ = $2; }; var: row col { $$ = lookat($1, $2); } | col row { $$ = lookat($2, $1); }; reduce_op: '+' { $$ = '+'; } | '*' { $$ = '*'; } ; term: var { $$ = new ('v', $1); } | K_FIXED term { $$ = new ('f', 0, $2); } | reduce_op '/' var ':' var { $$ = new (O_REDUCE($1), $3, $5); } | '(' e ')' { $$ = $2; } | '+' term { $$ = $2; } | '-' term { $$ = new ('m', 0, $2); } | NUMBER { $$ = new ('k', (double) $1); } | FNUMBER { $$ = new ('k', $1); } | '~' term { $$ = new ('~', 0, $2); } | '!' term { $$ = new ('~', 0, $2); } ; e: 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 ('~', 0, new ('>', $1, $4)); } | e '!' '=' e { $$ = new ('~', 0, new ('=', $1, $4)); } | e '>' '=' e { $$ = new ('~', 0, new ('<', $1, $4)); } ;