home *** CD-ROM | disk | FTP | other *** search
/ Dr. CD ROM (Annual Premium Edition) / premium.zip / premium / IBMOS2_1 / SC621.ZIP / sc621 / gram.y < prev    next >
Text File  |  1992-06-01  |  14KB  |  484 lines

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