home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / graphtal / yacc.y < prev    next >
Text File  |  1992-11-02  |  22KB  |  835 lines

  1. %{
  2. /*
  3.  * yacc.y - parser for graphtal.
  4.  *
  5.  * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified, and redistributed
  9.  * provided that this copyright notice is preserved on all copies.
  10.  *
  11.  * You may not distribute this software, in whole or in part, as part of
  12.  * any commercial product without the express consent of the authors.
  13.  *
  14.  * There is no warranty or other guarantee of fitness of this software
  15.  * for any purpose.  It is provided solely "as is".
  16.  *
  17.  */
  18.  
  19. // #ifdef _AIX
  20. //   #pragma alloca
  21. // # include <malloc.h>
  22. // # include <unistd.h>
  23. // #else
  24. # include <unistd.h>
  25. # ifndef alloca
  26. #  include <malloc.h>
  27. #  ifndef alloca
  28. #   define alloca
  29. #  endif
  30. # endif
  31. // #endif
  32.  
  33. #include <stdlib.h>
  34. #include <iostream.h>
  35.  
  36. #include "yyerror.h"
  37. #include "rcString.h"
  38. #include "LSystem.h"
  39. #include "Expression.h"
  40. #include "ExprItems.h"
  41. #include "table.h"
  42. #include "Color.h"
  43. #include "Options.h"
  44. #include "Primitives.h"
  45. #include "Hull.h"
  46. #include "Interpreter.h"
  47.  
  48. extern int yylex();
  49.  
  50. LSystem* lsystem = NULL;
  51.  
  52. declareTable(ExprSymtab, rcString, ExpressionPtr);
  53. implementTable(ExprSymtab, rcString, ExpressionPtr);
  54.  
  55. declareTable(IntSymtab, rcString, int);
  56. implementTable(IntSymtab, rcString, int);
  57.  
  58. declareTable(TableSymtab, rcString, TablePtr)
  59. implementTable(TableSymtab, rcString, TablePtr)
  60.  
  61. static ExprSymtab  GlobalConst(503);
  62. static ExprSymtab* LocalConst = new ExprSymtab(503);
  63. static IntSymtab*  FormalParam = new IntSymtab(17);
  64. static HullSymtab* theHulls = new HullSymtab(17);
  65. static TableSymtab theTables(17);
  66.  
  67. static int definingLocalConst = 0;
  68. static int nthParam = 0;
  69. static ProdModuleList* axiom = NULL;
  70. static DerivationList* derivation = NULL;
  71. %}
  72.  
  73. %union { double realnumber;
  74.      int intnumber;
  75.  
  76.      Vector* vector;
  77.      TransMatrix* trans;
  78.      GeoObject* geoObject;
  79.      Hull* hull;
  80.          DerivationList* derivations;
  81.      TableList* table_list;
  82.      Table* table;
  83.      ProductionList* prod_list;
  84.          Production* production;
  85.      Predecessor* predecessor;
  86.      NameList* name_list;
  87.      SuccessorList* succ_list;
  88.          Successor* successor;
  89.      ProdModuleList* module_list;
  90.      ProdModule* module;
  91.  
  92.      ExpressionList* expr_list;
  93.          Expression* expr;
  94.          Value* value;
  95.      rcString* name;
  96.        };  
  97.  
  98. %type <realnumber>  number
  99. %type <vector>      vector
  100. %type <trans>       transforms transformation
  101. %type <hull>        primitives
  102. %type <geoObject>   primitive
  103. %type <derivations> derivations
  104. %type <table_list>  tables
  105. %type <table>       table
  106. %type <prod_list>   productions
  107. %type <production>  production
  108. %type <predecessor> predecessor
  109. %type <succ_list>   successors
  110. %type <successor>   successor
  111. %type <module_list> modules
  112. %type <module>      module
  113. %type <name_list>   arguments parameters
  114. %type <name>        name
  115. %type <expr_list>   expr_list
  116. %type <expr>        expression condition no_argument one_argument
  117. %type <realnumber>  probability
  118. %type <intnumber>   steps
  119.  
  120. %token <value> tVALUE
  121. %token <name>  tNAME
  122. %token <name>  tCONSTANT
  123.  
  124. %token tLSYSTEM tTABLE tCONST
  125. %token tATTRIBUTES tDERIVATION tAXIOM tPITCH tROLL tTURN tANGLE
  126. %token tFORWARD tRANDOMIZE tINFINITY tTROPISM tWEIGHT
  127. %token tEYE tLOOKAT tUP tFOV
  128. %token tCONERES tSPHERERES
  129. %token tHULL tSPHERE tTRIANGLE tPLANE tCYLINDER tCONE
  130. %token tTRANSLATE tROTATE tSCALE tTRANSFORM 
  131.  
  132. %token tSIN tCOS tTAN tASIN tACOS tATAN tABS tSQRT tEXP tLOG tLOG10 tRAND
  133. %token tGAUSS
  134. %token tIF tTURTLEX tTURTLEY tTURTLEZ
  135.  
  136. %token tSCOPE   /* :: */
  137. %token tAND     /* && */
  138. %token tOR      /* || */
  139. %token '!'
  140. %token tEQ      /* == */
  141. %token tNEQ     /* != */
  142. %token tGEQ     /* >= */
  143. %token tLEQ     /* <= */
  144. %token '<'
  145. %token '>'
  146. %token tARROW   /* -> */
  147. %token tPOW     /* ** */
  148. %token '+' '-' '*' '/' '%' '^'
  149.  
  150. %left tOR        
  151. %left tAND
  152. %nonassoc tNEQ tEQ
  153. %nonassoc tGEQ tLEQ '<' '>'
  154. %left '+' '-'
  155. %left '*' '/' '%'
  156. %left tUMINUS '!'
  157. %right tPOW '^'
  158. %left tSCOPE
  159.  
  160.  
  161. %%
  162. lgrammar       : tLSYSTEM tNAME sc 
  163.                    global_const hulls tables attributes
  164.                  {
  165.            if (!axiom)
  166.              yyerror("no axiom defined");
  167.            if (!derivation)
  168.              yyerror("no derivation list defined");
  169.  
  170.            lsystem = new LSystem(Name($2), $6, axiom, derivation);
  171.            theOptions.hulls = theHulls;
  172.            delete $2;
  173.          }
  174.                ;
  175. global_const   : constant_def
  176.                  { definingLocalConst = 1; }
  177.                ;
  178.  
  179. constant_def   : /* empty */ 
  180.                | tCONST constants
  181.                ; 
  182.  
  183. constants      : constant 
  184.                | constants constant
  185.                ;
  186.  
  187. constant       : tCONSTANT '=' expression sc
  188.                  { 
  189.            if (definingLocalConst) {
  190.              if (!LocalConst->insert(*$1, $3->simplify()))
  191.                yyerror("Constant " + *$1 + " already defined");
  192.            }
  193.            else {
  194.              if (!GlobalConst.insert(*$1, $3->simplify()))
  195.                yyerror("Constant " + *$1 + " already defined");
  196.            }
  197.            delete $1;
  198.          }
  199.                ;
  200.  
  201. hulls          : /* empty */
  202.                | hulls hull
  203.                ;
  204.  
  205. hull           : tHULL tNAME '{' primitives '}' sc
  206.                  {
  207.            if (!theHulls->insert(*$2, $4))
  208.              yyerror("hull " + *$2 + " already defined");
  209.            delete $2;
  210.          }
  211.                ;
  212.  
  213. primitives     : primitive
  214.                  {
  215.            $$ = new Hull;
  216.            $$->addPrimitive($1);
  217.          }
  218.                | primitive transforms
  219.                  {
  220.            if (!$1->setTransform($2)) 
  221.              yyerror("singular matrix");
  222.  
  223.            $$ = new Hull;
  224.            $$->addPrimitive($1);
  225.          }
  226.                | primitives primitive
  227.                  { 
  228.            $$ = $1;
  229.            $$->addPrimitive($2);
  230.          }
  231.                | primitives primitive transforms
  232.                  { 
  233.            if (!$2->setTransform($3)) 
  234.              yyerror("singular matrix");
  235.  
  236.            $$ = $1;
  237.            $$->addPrimitive($2);
  238.          }
  239.                ;
  240.  
  241. primitive      : tSPHERE number vector
  242.                  {
  243.            if (($$ = Sphere::create($2, *$3)) == NULL)
  244.              yyerror("degenerate sphere");
  245.  
  246.            delete $3;
  247.                  }
  248.                | tTRIANGLE vector vector vector 
  249.                  {
  250.            if (($$ = Triangle::create(*$2, *$3, *$4)) == NULL)
  251.              yyerror("degenerate triangle");
  252.  
  253.            delete $2; 
  254.            delete $3; 
  255.            delete $4;
  256.                  }
  257.                | tPLANE vector vector 
  258.                  {
  259.            if (($$ = Plane::create(*$2, *$3)) == NULL)
  260.              yyerror("degenerate plane normal");
  261.  
  262.            delete $2; 
  263.            delete $3;
  264.                  }
  265.                | tCYLINDER number vector vector
  266.                  {
  267.            if (($$ = Cylinder::create($2, *$3, *$4)) == NULL)
  268.              yyerror("degenerate cylinder");
  269.  
  270.            delete $3; 
  271.            delete $4;
  272.                  }
  273.                | tCONE number vector number vector
  274.                  {
  275.            if (($$ = Cone::create($2, *$3, $4, *$5)) == NULL)
  276.              yyerror("degenerate cone");
  277.  
  278.            delete $3; 
  279.            delete $5;
  280.                  }
  281.                ;
  282.  
  283. vector         : number number number
  284.                  { 
  285.            $$ = new Vector($1, $2, $3);
  286.          }
  287.                ;
  288.  
  289. number         : tVALUE
  290.                  { 
  291.            $$ = *$1; 
  292.            delete $1;
  293.          }
  294.                | '-' tVALUE
  295.                  {
  296.            $$ = *$2;
  297.            $$ = -$$;
  298.            delete $2;
  299.          }
  300.                | '+' tVALUE
  301.                  { 
  302.            $$ = *$2; 
  303.            delete $2;
  304.          }
  305.                | tNAME
  306.                  {
  307.            Expression *expr;
  308.  
  309.            if (!GlobalConst.lookup(*$1, expr))
  310.              yyerror(*$1 + " unknown");
  311.            else
  312.                      $$ = expr->evaluate();
  313.  
  314.            delete $1;
  315.          }
  316.                ;
  317.  
  318. transforms     : transformation
  319.                  { 
  320.            $$ = $1;
  321.              }
  322.                | transforms transformation
  323.                  {
  324.            (*$1) *= (*$2);
  325.            $$ = $1;
  326.            delete $2;
  327.          } 
  328.                ;
  329.  
  330. transformation : tTRANSLATE vector
  331.                  {
  332.            $$ = new TransMatrix;
  333.            $$->translate(*$2);
  334.            delete $2;
  335.          }
  336.                | tSCALE number number number
  337.                  {
  338.            $$ = new TransMatrix;
  339.            $$->scale($2, $3, $4);
  340.          }
  341.                | tROTATE vector number
  342.                  {
  343.            $$ = new TransMatrix;
  344.            $$->rotate(*$2, dtor($3));
  345.            delete $2;
  346.          }
  347.                | tTRANSFORM vector vector vector
  348.                  {
  349.            $$ = new TransMatrix(*$2, *$3, *$4);
  350.            delete $2;
  351.            delete $3;
  352.            delete $4;
  353.          }
  354.                | tTRANSFORM vector vector vector vector
  355.                  {
  356.            $$ = new TransMatrix(*$2, *$3, *$4, *$5);
  357.            delete $2;
  358.            delete $3;
  359.            delete $4;
  360.            delete $5;
  361.          }
  362.                ;
  363.  
  364. tables         : table 
  365.                  { 
  366.            $$ = new TableList(1);
  367.            $$->append($1);
  368.          }
  369.                | tables table 
  370.                  { 
  371.            $$ = $1;
  372.            $$->append($2);
  373.          }
  374.                ;
  375.  
  376. table          : tTABLE tNAME '{' constant_def productions '}' sc
  377.                  {
  378.            Table *table = new Table(Name($2), $5);
  379.            if (!theTables.insert(*$2, table))
  380.              yyerror("Table " + *$2 + " already defined");
  381.            else {
  382.              // delete current local constants
  383.              delete LocalConst;
  384.              LocalConst = new ExprSymtab(503);
  385.  
  386.              $$ = table;
  387.            }
  388.            delete $2;
  389.          }
  390.                ;
  391.  
  392. productions    : production 
  393.                  { 
  394.            nthParam = 0; 
  395.            $$ = new ProductionList;
  396.            $$->append($1);
  397.          } 
  398.                | productions production 
  399.                  { 
  400.            nthParam = 0; 
  401.            $$ = $1;
  402.            $$->append($2);
  403.          }
  404.                ;
  405.  
  406. production     : predecessor successors sc
  407.                  { 
  408.            $$ = new Production($1, NULL, $2);
  409.            if ($$->cumulateProbability())
  410.              yyerror("Sum of production probabilities is > 1");
  411.  
  412.                    delete FormalParam;
  413.            FormalParam = new IntSymtab(17);
  414.          }
  415.                | predecessor condition successors sc
  416.                  {
  417.            $$ = new Production($1, $2, $3);
  418.            if ($$->cumulateProbability())
  419.              yyerror("Sum of production probabilities is > 1");
  420.  
  421.                    delete FormalParam;
  422.            FormalParam = new IntSymtab(17);
  423.          }
  424.                ;
  425.  
  426. predecessor    : name
  427.                  { 
  428.            $$ = new Predecessor(Name($1), NULL); 
  429.            delete $1;
  430.          }
  431.                | name arguments
  432.                  { 
  433.            $$ = new Predecessor(Name($1), $2); 
  434.            delete $1;
  435.          }
  436.                ;
  437.  
  438. name           : '{'
  439.                  { $$ = new rcString("{"); }
  440.                | '}'
  441.                  { $$ = new rcString("}"); }
  442.                | '['
  443.                  { $$ = new rcString("["); }
  444.                | ']'
  445.                  { $$ = new rcString("]"); }
  446.                | '^'
  447.                  { $$ = new rcString("^"); }
  448.                | '&'
  449.                  { $$ = new rcString("&"); }
  450.                | '+'
  451.                  { $$ = new rcString("+"); }
  452.                | '-'
  453.                  { $$ = new rcString("-"); }
  454.                | '\\'
  455.                  { $$ = new rcString("\\"); }
  456.                | '/'
  457.                  { $$ = new rcString("/"); }
  458.                | '|'
  459.                  { $$ = new rcString("|"); }
  460.                | '$'
  461.                  { $$ = new rcString("$"); }
  462.                | '.'
  463.                  { $$ = new rcString("."); }
  464.                | '%'
  465.                  { $$ = new rcString("~"); }
  466.                | tNAME
  467.                  { $$ = $1; }
  468.                ;
  469.  
  470. arguments      : '(' parameters rp
  471.                  { $$ = $2; }
  472.                ;
  473.  
  474. parameters    : tNAME
  475.                  { 
  476.            $$ = new NameList(1);
  477.            $$->append(new Name($1));
  478.            if (!FormalParam->insert(*$1, nthParam++))
  479.              yyerror("Parameter " + *$1 + " already used");
  480.  
  481.            delete $1;
  482.          }
  483.                | parameters ',' tNAME
  484.                  { 
  485.            $$ = $1;
  486.            $$->append(new Name($3));
  487.            if (!FormalParam->insert(*$3, nthParam++))
  488.              yyerror("Parameter " + *$3 + " already used");
  489.  
  490.            delete $3;
  491.          }
  492.                ;
  493.  
  494. condition      : ':' expression 
  495.                  { $$ = $2->simplify(); }
  496.                ;
  497.  
  498. successors     : successor
  499.                  {
  500.            $$ = new SuccessorList(1);
  501.            $$->append($1);
  502.          }
  503.                | successors successor
  504.                  { 
  505.            $$ = $1;
  506.            $$->append($2);
  507.          }
  508.                ;
  509.  
  510. successor      : tARROW probability modules 
  511.                  {
  512.            $$ = new Successor($2, $3);
  513.          }
  514.                | tARROW probability 
  515.                  {
  516.            $$ = new Successor($2, NULL);
  517.          }
  518.                ;
  519.  
  520. probability    : /* empty */    { $$ = 1.0; }
  521.                | '(' tVALUE ')' { $$ = *$2;
  522.                   delete $2;
  523.                 } 
  524.                ;    
  525.  
  526. modules        : module
  527.                  {
  528.            $$ = new ProdModuleList(1);
  529.            $$->append($1);
  530.          }
  531.                | modules module
  532.                  {
  533.            $$ = $1;
  534.            $$->append($2);
  535.          }
  536.                ;
  537.  
  538. module         : name
  539.                  {
  540.            $$ = new ProdModule(Name($1), NULL);
  541.            delete $1;
  542.          }
  543.                | name '(' expr_list rp
  544.                  {
  545.            $$ = new ProdModule(Name($1), $3);
  546.            delete $1;
  547.          }
  548.                ;
  549.  
  550. expr_list      : expression
  551.                  {
  552.            $$ = new ExpressionList(1);
  553.            $$->append($1->simplify());
  554.          }
  555.                | expr_list ',' expression
  556.                  {
  557.            $1->append($3->simplify());
  558.            $$ = $1;
  559.          }
  560.                ;
  561.  
  562. expression     : tVALUE { $$ = new Expression(new ValueItem($1));
  563.               delete $1;
  564.             }
  565.                | tTURTLEX
  566.                  { $$ = new Expression(new Variable(Name("tx"),
  567.                           Interpreter::getTx())); 
  568.          }
  569.                | tTURTLEY
  570.                  { $$ = new Expression(new Variable(Name("ty"), 
  571.                           Interpreter::getTy())); }
  572.                | tTURTLEZ
  573.                  { $$ = new Expression(new Variable(Name("tz"), 
  574.                           Interpreter::getTz())); }
  575.                | tNAME  
  576.                  { Expression *expr;
  577.            int nth;
  578.            
  579.            // a formal parameter, local or global constant ?
  580.            if (!FormalParam->lookup(*$1, nth)) {
  581.              if (!LocalConst->lookup(*$1, expr)) {
  582.                if (!GlobalConst.lookup(*$1, expr))
  583.              yyerror("`" + *$1 + "' unknown");
  584.                else
  585.              $$ = new Expression(*expr);
  586.              }
  587.              else
  588.                $$ = new Expression(*expr);
  589.            }
  590.            else
  591.              $$ = new Expression(new Variable(Name($1), 
  592.                               Formals(nth)));
  593.            delete $1;
  594.          }
  595.                | tSCOPE tNAME
  596.                  {
  597.            Expression *expr;
  598.  
  599.            if (!GlobalConst.lookup(*$2, expr))
  600.              yyerror("::" + *$2 + " unknown");
  601.            else
  602.              $$ = new Expression(*expr);
  603.  
  604.            delete $2;
  605.          }
  606.                | expression tOR  expression
  607.                  { $$ = new Expression(new Or,  $1, $3); }
  608.                | expression tAND expression
  609.                  { $$ = new Expression(new And, $1, $3); }
  610.                | expression tEQ  expression
  611.                  { $$ = new Expression(new Eq,  $1, $3); }
  612.                | expression tNEQ expression
  613.                  { $$ = new Expression(new Neq, $1, $3); }
  614.                | expression tGEQ expression
  615.                  { $$ = new Expression(new Geq, $1, $3); }
  616.                | expression tLEQ expression
  617.                  { $$ = new Expression(new Leq, $1, $3); }
  618.                | expression '>' expression
  619.                  { $$ = new Expression(new Gt,  $1, $3); }
  620.                | expression '<' expression
  621.                  { $$ = new Expression(new Lt,  $1, $3); }
  622.                | '!' expression
  623.                  { $$ = new Expression(new Not,  $2); }
  624.  
  625.                | expression '+' expression 
  626.                  { $$ = new Expression(new Add, $1, $3); }
  627.                | expression '-' expression
  628.                  { $$ = new Expression(new Sub, $1, $3); }
  629.                | expression '*' expression
  630.                  { $$ = new Expression(new Mul, $1, $3); }
  631.                | expression '/' expression
  632.                  { $$ = new Expression(new Div, $1, $3); }
  633.                | expression '%' expression
  634.                  { $$ = new Expression(new Mod, $1, $3); }
  635.                | expression tPOW expression 
  636.                  { $$ = new Expression(new Pow, $1, $3); }
  637.                | expression '^' expression 
  638.                  { $$ = new Expression(new Pow, $1, $3); }
  639.                | '-' expression %prec tUMINUS
  640.                  { $$ = new Expression(new Uminus,  $2); }
  641.   
  642.                | tSIN  one_argument
  643.                  { $$ = new Expression(new Sin, $2); }                
  644.                | tCOS  one_argument
  645.                  { $$ = new Expression(new Cos, $2); }               
  646.                | tTAN  one_argument
  647.                  { $$ = new Expression(new Tan, $2); }               
  648.                | tASIN one_argument
  649.                  { $$ = new Expression(new Asin, $2); }                
  650.                | tACOS one_argument
  651.                  { $$ = new Expression(new Acos, $2); }               
  652.                | tATAN one_argument
  653.                  { $$ = new Expression(new Atan, $2); }               
  654.                | tABS one_argument
  655.                  { $$ = new Expression(new Abs, $2); }               
  656.                | tSQRT one_argument
  657.                  { $$ = new Expression(new Sqrt, $2); }               
  658.                | tEXP one_argument
  659.                  { $$ = new Expression(new Exp, $2); }               
  660.                | tLOG one_argument
  661.                  { $$ = new Expression(new Log, $2); }               
  662.                | tLOG10 one_argument
  663.                  { $$ = new Expression(new Log, $2); }
  664.                | tRAND no_argument
  665.                  { $$ = new Expression(new Rand); }
  666.                | tGAUSS no_argument
  667.                  { $$ = new Expression(new Gauss); }
  668.                | tIF '(' expression ',' expression ',' expression rp
  669.                  { $$ = new Expression(new If, $3, $5, $7); }
  670.                | tNAME no_argument
  671.                  { 
  672.            yyerror("Function " + *$1 + "() unknown"); 
  673.          }
  674.                | tNAME '(' expr_list rp
  675.                  { 
  676.            yyerror("Function " + *$1 + "(arguments) unknown"); 
  677.          }
  678.                | '(' expression rp
  679.          { $$ = $2; }
  680.                ;
  681.  
  682. no_argument    : '(' rp
  683.                  { $$ = NULL; }
  684.                ;
  685. one_argument   : '(' expression rp
  686.                  { $$ = $2->simplify(); }
  687.                ;
  688.  
  689. attributes     : tATTRIBUTES '{' attr_list  '}' sc 
  690.                ;
  691.  
  692. attr_list    : /* empty */
  693.                | attr_list attr_item
  694.                ;
  695.  
  696. attr_item    : tDERIVATION derivations sc
  697.                  { derivation = $2; }
  698.                | tAXIOM modules sc
  699.                  { axiom = $2; }
  700.                | tPITCH  expression sc
  701.                  { 
  702.            theOptions.defaultPitch = dtor($2->evaluate());
  703.            delete $2;
  704.          }
  705.                | tROLL expression sc
  706.                  { theOptions.defaultRoll = dtor($2->evaluate());
  707.            delete $2;
  708.          }
  709.                | tTURN expression sc
  710.                  { 
  711.            theOptions.defaultTurn = dtor($2->evaluate());
  712.            delete $2;
  713.          }
  714.                | tANGLE expression sc
  715.                  { 
  716.            theOptions.defaultPitch = 
  717.            theOptions.defaultRoll  = 
  718.            theOptions.defaultTurn  =  dtor($2->evaluate());
  719.            delete $2;
  720.          }
  721.                | tFORWARD expression sc
  722.                  { 
  723.            theOptions.defaultForward = $2->evaluate();
  724.            delete $2;
  725.          }
  726.                | tRANDOMIZE sc
  727.                  { 
  728.            long now;
  729.  
  730. // #if defined(_AIX)
  731. //              stime(&now);
  732. //#elif defined(__DECCXX)
  733.  
  734. #if defined(__DECCXX)
  735.            now = getpid();
  736. #else
  737.              time(&now);
  738. #endif
  739.            if (theOptions.verbose) 
  740.              cerr << "randomize " << now << "\n";
  741.            srand48(now);
  742.          }
  743.                | tRANDOMIZE expression  sc
  744.                  { 
  745.            srand48((long)$2->evaluate()); 
  746.            delete $2;
  747.          }
  748.                | tTROPISM  expression ',' expression ',' expression sc
  749.                  { 
  750.            theOptions.tropismX = $2->simplify();
  751.            theOptions.tropismY = $4->simplify();
  752.            theOptions.tropismZ = $6->simplify();
  753.          }
  754.                | tWEIGHT expression sc
  755.                  { 
  756.            theOptions.weight = $2->simplify();
  757.          }
  758.                | tEYE expression ',' expression ',' expression sc
  759.                  {
  760.            theOptions.autoscale = 0;
  761.            theOptions.eye = 
  762.              Vector($2->evaluate(), $4->evaluate(), $6->evaluate());
  763.            delete $2; delete $4; delete $6;
  764.          }
  765.                | tLOOKAT expression ',' expression ',' expression sc
  766.                  {
  767.            theOptions.autoscale = 0;
  768.            theOptions.lookat = 
  769.              Vector($2->evaluate(), $4->evaluate(), $6->evaluate());
  770.            delete $2; delete $4; delete $6;
  771.          }
  772.                | tUP expression ',' expression ',' expression sc
  773.                  {
  774.            theOptions.up = 
  775.              Vector($2->evaluate(), $4->evaluate(), $6->evaluate());
  776.            delete $2; delete $4; delete $6;
  777.          }
  778.                | tFOV expression sc
  779.                  {
  780.            theOptions.fov = $2->evaluate();
  781.            delete $2;
  782.          }
  783.                | tCONERES tVALUE sc
  784.                  {
  785.            theOptions.coneResolution = (int) *$2;
  786.            delete $2;
  787.          }
  788.                | tSPHERERES tVALUE sc
  789.                  {
  790.            theOptions.sphereResolution = (int) *$2;
  791.            delete $2;
  792.          }
  793.                ;
  794.  
  795. derivations    : tNAME steps
  796.                  { Table *t;
  797.  
  798.            if (!theTables.lookup(*$1, t))
  799.              yyerror("Unknown table " + *$1);
  800.            else {
  801.              $$ = new DerivationList(1);
  802.              $$->append(new DerivationItem(t,$2));
  803.            }
  804.            delete $1;
  805.          }
  806.                | derivations ',' tNAME steps
  807.                  { Table *t;
  808.  
  809.            $$ = $1;
  810.            if (!theTables.lookup(*$3, t))
  811.              yyerror("Unknown table " + *$3);
  812.            else
  813.              $$->append(new DerivationItem(t,$4));
  814.  
  815.            delete $3;
  816.          }
  817.                ;
  818.                
  819. steps          : /* empty */
  820.                  { $$ = 1; }
  821.                | '(' expression rp 
  822.                  { $$ = (int) real($2->evaluate());
  823.            delete $2;
  824.          }
  825.                | '(' tINFINITY rp 
  826.                  { $$ = -1; }
  827.                ;
  828.  
  829. sc             : ';'  { yyerrok; } ;
  830. rp             : ')'  { yyerrok; } ;
  831.  
  832.  
  833. %%
  834.  
  835.