%{ #include #include #include "main/Scene.h" #include "main/Material.h" #include "util/Vector.h" #include "util/refptr.h" #include "shapes/Shape.h" /* includes all shape types */ #include "nodes.h" using namespace std; extern "C" { int yylex(void); } extern FILE * yyin; extern char * yytext; void yyerror(const char * str) { fprintf(stderr, "error: %s\n", str); } int yywrap() { return 1; } #define YYSTYPE refptr static Scene * g_scene; %} %token PLUS; %token MINUS; %token STAR; %token DIVIDE; %token MOD; %token SEMICOLON; %token COLON; %token QUESTION; %token DOLLAR; %token DOT; %token DQUOTE; %token SQUOTE; %token COMMA; %token LCURLY; %token RCURLY; %token LBRACKET; %token RBRACKET; %token LPAREN; %token RPAREN; %token LESS; %token GREATER; %token DEC_NUMBER; %token REAL_NUMBER; %token AMBIENT; %token BOX; %token CAMERA; %token DIFFUSE; %token HEIGHT; %token INTERSECT; %token LIGHT; %token LOOKAT; %token MATERIAL; %token MULTISAMPLE; %token OPTIONS; %token PLANE; %token POSITION; %token REFLECTANCE; %token SCENE; %token SHININESS; %token SIZE; %token SPECULAR; %token SPHERE; %token SUBTRACT; %token UNION; %token UP; %token VFOV; %token WIDTH; %% scene: SCENE LCURLY scene_items RCURLY { refptr node = $3; while ( ! node.isNull() ) { /* process this scene item */ refptr thisNode = node->the_Node; switch (thisNode->type) { case Node_Shape: g_scene->m_shapes.push_back(thisNode->the_Shape); break; case Node_Camera: break; case Node_Light: break; case Node_Options: break; } node = node->the_tail; } } ; boolean_items: shape shape boolean_items_more { $$ = new Node(); $$->the_Node = $1; $$->the_tail = new Node(); $$->the_tail->the_Node = $2; $$->the_tail->the_tail = new Node(); $$->the_tail->the_tail->the_Node = $3; } ; boolean_items_more: /* empty */ | material boolean_items_more ; box: BOX LPAREN vector RPAREN LCURLY box_items RCURLY ; box_items: shape_items { $$ = $1; } ; camera: CAMERA LCURLY camera_items RCURLY { Vector default_position(0, -1, 0); Vector default_look_at(0, 0, 0); Vector default_up(0, 0, 1); } ; camera_items: /* empty */ | camera_item camera_items ; camera_item: POSITION vector { $$ = new Node(); $$->type = POSITION; $$->the_Vector = $2->the_Vector; } | LOOKAT vector { $$ = new Node(); $$->type = LOOKAT; $$->the_Vector = $2->the_Vector; } | UP vector { $$ = new Node(); $$->type = UP; $$->the_Vector = $2->the_Vector; } | VFOV vector { $$ = new Node(); $$->type = VFOV; $$->the_Vector = $2->the_Vector; } ; intersect: INTERSECT LCURLY boolean_items RCURLY ; light: LIGHT LCURLY light_items RCURLY { $$ = new Node(); refptr light = new Light(); refptr node = $3; while ( ! node.isNull() ) { switch (node->type) { case POSITION: break; } node = node->the_tail; } } ; light_items: /* empty */ | light_item light_items { $$ = new Node(); $$->the_Node = $1; $$->the_tail = $2; } ; light_item: POSITION vector { $$ = new Node(); $$->type = POSITION; $$->the_Vector = $2->the_Vector; } | DIFFUSE vector { $$ = new Node(); $$->type = DIFFUSE; $$->the_Color = new Color(* $2->the_Vector); } | SPECULAR vector { $$ = new Node(); $$->type = SPECULAR; $$->the_Color = new Color(* $2->the_Vector); } ; material: MATERIAL LCURLY material_items RCURLY { $$ = new Node(); refptr material = new Material(); refptr node = $3; while ( ! node.isNull() ) { switch (node->type) { case AMBIENT: material->setAmbientColor(*node->the_Color); break; case DIFFUSE: material->setDiffuseColor(* node->the_Color); break; case SPECULAR: material->setSpecularColor(* node->the_Color); break; case SHININESS: material->setShininess(* node->the_double); break; case REFLECTANCE: material->setReflectance(* node->the_double); break; } node = node->the_Node; } } ; material_items: /* empty */ | material_item material_items { $$ = new Node(); $$->the_Node = $1; $$->the_tail = $2; } ; material_item: AMBIENT vector { $$ = new Node(); $$->type = AMBIENT; $$->the_Color = new Color(* $2->the_Vector); } | DIFFUSE vector { $$ = new Node(); $$->type = DIFFUSE; $$->the_Color = new Color(* $2->the_Vector); } | SPECULAR vector { $$ = new Node(); $$->type = SPECULAR; $$->the_Color = new Color(* $2->the_Vector); } | REFLECTANCE number { $$ = new Node(); $$->type = REFLECTANCE; $$->the_double = $2->the_double; } | SHININESS number { $$ = new Node(); $$->type = SHININESS; $$->the_double = $2->the_double; } ; number: DEC_NUMBER { double * ptr = new double; *ptr = atoi(yytext); $$ = new Node(); $$->the_double = ptr; } | REAL_NUMBER { double * ptr = new double; *ptr = atof(yytext); $$ = new Node(); $$->the_double = ptr; } ; options: OPTIONS LCURLY options_items RCURLY { $$ = $3; } ; options_items: /* empty */ | options_item options_items { $$ = new Node(); $$->the_Node = $1; $$->the_tail = $2; } ; options_item: WIDTH number { $$ = new Node(); $$->type = WIDTH; $$->the_double = $2->the_double; } | HEIGHT number { $$ = new Node(); $$->type = HEIGHT; $$->the_double = $2->the_double; } | MULTISAMPLE number { $$ = new Node(); $$->type = MULTISAMPLE; $$->the_double = $2->the_double; } ; plane: PLANE LPAREN vector COMMA number RPAREN LCURLY plane_items RCURLY { Plane * plane = new Plane((*($3->the_Vector))[0], (*($3->the_Vector))[1], (*($3->the_Vector))[2], *($5->the_double)); $$ = new Node(); $$->the_Shape = plane; } ; plane_items: shape_items { $$ = $1; } ; scene_items: /* empty */ | scene_item scene_items { $$ = new Node(); $$->the_Node = $1; $$->the_tail = $2; } ; scene_item: camera { $$ = $1; $$->type = Node_Camera; } | shape { $$ = $1; $$->type = Node_Shape; } | options { $$ = $1; $$->type = Node_Options; } | light { $$ = $1; $$->type = Node_Light; } ; shape: plane { $$ = $1; } | sphere { $$ = $1; } | box { $$ = $1; } | union { $$ = $1; } | intersect { $$ = $1; } | subtract { $$ = $1; } ; shape_items: /* empty */ | material { $$ = $1; } ; sphere: SPHERE LPAREN number RPAREN LCURLY sphere_items RCURLY { Sphere * sphere = new Sphere(*($3->the_double)); $$ = new Node(); $$->the_Shape = sphere; } ; sphere_items: shape_items { $$ = $1; } ; subtract: SUBTRACT LCURLY boolean_items RCURLY ; union: UNION LCURLY boolean_items RCURLY ; vector: LESS number COMMA number COMMA number GREATER { Vector * ptr = new Vector(); (*ptr)[0] = * $2->the_double; (*ptr)[1] = * $4->the_double; (*ptr)[2] = * $6->the_double; $$ = new Node(); $$->the_Vector = ptr; } ; %% int Scene::parse(const char * fileName) { g_scene = this; yyin = fopen(fileName, "r"); if (yyin == NULL) { cerr << "Failed to open file '" << fileName << "'" << endl; return -1; } yyparse(); return 0; } Node::Node() { type = -1; }