%{ #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 */ 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; } class Node { public: Node(); int type; refptr the_double; refptr the_Material; refptr the_Node; refptr the_tail; refptr the_Shape; refptr the_Vector; }; enum Node_Type { Node_Shape = 0x42001, /* don't clash with bison token namespace */ Node_Camera, Node_Options }; #define YYSTYPE refptr %} %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 BOX; %token CAMERA; %token COLOR; %token HEIGHT; %token INTERSECT; %token LOOKAT; %token MATERIAL; %token MULTISAMPLE; %token OPTIONS; %token PLANE; %token POSITION; %token REFLECTANCE; %token SCENE; %token SHININESS; %token SIZE; %token SPHERE; %token SUBTRACT; %token UNION; %token UP; %token VFOV; %token WIDTH; %% scene: SCENE LCURLY scene_items RCURLY { } ; boolean_items: shape shape boolean_items_more ; 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 ; material: MATERIAL LCURLY material_items RCURLY ; material_items: /* empty */ | material_item material_items ; material_item: COLOR vector { $$ = new Node(); $$->type = COLOR; $$->the_Vector = $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; } ; 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) { yyin = fopen(fileName, "r"); if (yyin == NULL) { cerr << "Failed to open file '" << fileName << "'" << endl; return -1; } yyparse(); return 0; } Node::Node() { type = -1; }