%{ #include #include #include "util/Vector.h" #include "util/refptr.h" #include "nodes.h" #include "parser.h" #include "parser.tab.hh" /* bison-generated header with YY[SL]TYPE */ using namespace std; #define yyerror(msg) errFunc(msg, &yylloc) int yylex(YYSTYPE *, YYLTYPE *); extern FILE * yyin; void errFunc(const char * str, YYLTYPE * yyllocp); int yywrap() { return 1; } static refptr parsed_scene_node; %} %pure-parser %locations %error-verbose %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 AMBIENT_OCCLUSION; %token BOX; %token CAMERA; %token COLOR; %token CYL; %token DEFINE; %token DIFFUSE; %token EXPOSURE; %token HEIGHT; %token INTERSECT; %token JITTER; %token LIGHT; %token LOOKAT; %token MATERIAL; %token MAXDEPTH; %token MULTISAMPLE; %token OPTIONS; %token PLANE; %token POSITION; %token RADIUS; %token REFLECTANCE; %token ROTATE; %token SCALE; %token SCENE; %token SHININESS; %token SIZE; %token SPECULAR; %token SPHERE; %token SUBTRACT; %token TRANSLATE; %token TRANSPARENCY; %token UNION; %token UP; %token VFOV; %token WIDTH; %token IDENTIFIER; %% scene: SCENE LCURLY scene_items RCURLY { $$ = new SceneNode(); $$->addChildren($3); parsed_scene_node = $$; } ; bool_items: /* empty */ | bool_item bool_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; bool_item: shape | shape_item ; box: BOX LCURLY box_items RCURLY { $$ = new BoxNode(); $$->addChildren($3); } ; box_items: /* empty */ | box_item box_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; box_item: SIZE vector { $$ = new SizeNode($2->getVector()); } | shape_item { $$ = $1; } ; camera: CAMERA LCURLY camera_items RCURLY { $$ = new CameraNode(); $$->addChildren($3); } ; camera_items: /* empty */ | camera_item camera_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; camera_item: POSITION vector { $$ = new PositionNode($2->getVector()); } | LOOKAT vector { $$ = new LookAtNode($2->getVector()); } | UP vector { $$ = new UpNode($2->getVector()); } | VFOV number { $$ = new VFOVNode($2->getNumber()); } ; cyl: CYL LCURLY cyl_items RCURLY { $$ = new CylNode(); $$->addChildren($3); } ; cyl_items: /* empty */ | cyl_item cyl_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; cyl_item: SIZE vector { $$ = new SizeNode($2->getVector()); } | shape_item { $$ = $1; } ; intersect: INTERSECT LCURLY bool_items RCURLY { $$ = new IntersectNode(); $$->addChildren($3); } ; jitter: JITTER number { $$ = new JitterNode($2->getInteger()); } ; light: LIGHT LCURLY light_items RCURLY { $$ = new LightNode(); $$->addChildren($3); } ; light_items: /* empty */ | light_item light_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; light_item: POSITION vector { $$ = new PositionNode($2->getVector()); } | DIFFUSE vector { $$ = new DiffuseNode($2->getVector()); } | SPECULAR vector { $$ = new SpecularNode($2->getVector()); } | COLOR vector { $$ = new ColorNode($2->getVector()); } | radius { $$ = $1; } | jitter { $$ = $1; } ; material: MATERIAL LCURLY material_items RCURLY { $$ = new MaterialNode(); $$->addChildren($3); } ; material_items: /* empty */ | material_item material_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; material_item: COLOR vector { $$ = new ColorNode($2->getVector()); } | AMBIENT vector { $$ = new AmbientNode($2->getVector()); } | DIFFUSE vector { $$ = new DiffuseNode($2->getVector()); } | SPECULAR vector { $$ = new SpecularNode($2->getVector()); } | REFLECTANCE number { $$ = new ReflectanceNode($2->getNumber()); } | SHININESS number { $$ = new ShininessNode($2->getNumber()); } | TRANSPARENCY number { $$ = new TransparencyNode($2->getNumber()); } ; material_definition: DEFINE MATERIAL IDENTIFIER LCURLY material_items RCURLY { $$ = new MaterialDefinitionNode($3->getString()); $$->addChildren($5); } ; material_ref: MATERIAL IDENTIFIER { $$ = new MaterialRefNode($2->getString()); } ; number: DEC_NUMBER { $$ = $1; } | REAL_NUMBER { $$ = $1; } ; options: OPTIONS LCURLY options_items RCURLY { $$ = new OptionsNode(); $$->addChildren($3); } ; options_items: /* empty */ | options_item options_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; options_item: WIDTH DEC_NUMBER { $$ = new WidthNode($2->getInteger()); } | HEIGHT DEC_NUMBER { $$ = new HeightNode($2->getInteger()); } | MULTISAMPLE DEC_NUMBER { $$ = new MultisampleNode($2->getInteger()); } | MAXDEPTH DEC_NUMBER { $$ = new MaxDepthNode($2->getInteger()); } | EXPOSURE number { $$ = new ExposureNode($2->getNumber()); } | AMBIENT vector { $$ = new AmbientNode($2->getVector()); } | AMBIENT_OCCLUSION DEC_NUMBER { $$ = new AmbientOcclusionNode($2->getInteger()); } ; plane: PLANE LCURLY plane_items RCURLY { $$ = new PlaneNode(); $$->addChildren($3); } ; plane_items: /* empty */ | plane_item plane_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; plane_item: POSITION vector COMMA number { $$ = new PlanePositionNode($2->getVector(), $4->getNumber()); } | shape_item { $$ = $1; } ; radius: RADIUS number { $$ = new RadiusNode($2->getNumber()); } ; scene_items: /* empty */ | scene_item scene_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; scene_item: camera { $$ = $1; } | shape { $$ = $1; } | options { $$ = $1; } | light { $$ = $1; } | transform_block { $$ = $1; } | material_definition { $$ = $1; } ; shape: plane { $$ = $1; } | sphere { $$ = $1; } | box { $$ = $1; } | cyl { $$ = $1; } | union { $$ = $1; } | intersect { $$ = $1; } | subtract { $$ = $1; } ; shape_item: material { $$ = $1; } | material_ref { $$ = $1; } | transform { $$ = $1; } ; sphere: SPHERE LCURLY sphere_items RCURLY { $$ = new SphereNode(); $$->addChildren($3); } ; sphere_items: /* empty */ | sphere_item sphere_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; sphere_item: radius { $$ = $1; } | shape_item { $$ = $1; } ; subtract: SUBTRACT LCURLY bool_items RCURLY { $$ = new SubtractNode(); $$->addChildren($3); } ; transform: TRANSLATE vector { $$ = new TranslateNode($2->getVector()); } | ROTATE number COMMA vector { $$ = new RotateNode($2->getNumber(), $4->getVector()); } | SCALE vector { $$ = new ScaleNode($2->getVector()); } ; transform_block: TRANSLATE vector LCURLY transform_block_items RCURLY { $$ = new TranslateBlockNode($2->getVector()); $$->addChildren($4); } | ROTATE number COMMA vector LCURLY transform_block_items RCURLY { $$ = new RotateBlockNode($2->getNumber(), $4->getVector()); $$->addChildren($6); } | SCALE vector LCURLY transform_block_items RCURLY { $$ = new ScaleBlockNode($2->getVector()); $$->addChildren($4); } ; transform_block_items: /* empty */ | transform_block_item transform_block_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; transform_block_item: transform_block { $$ = $1; } | light { $$ = $1; } | shape { $$ = $1; } ; union: UNION LCURLY bool_items RCURLY { $$ = new UnionNode(); $$->addChildren($3); } ; vector: LESS number COMMA number COMMA number GREATER { refptr vec = new Vector(); (*vec)[0] = $2->getNumber(); (*vec)[1] = $4->getNumber(); (*vec)[2] = $6->getNumber(); $$ = new VectorNode(vec); } ; %% refptr parse(const char * fileName) { yyin = fopen(fileName, "r"); if (yyin == NULL) { cerr << "Failed to open file '" << fileName << "'" << endl; return refptr(NULL); } if (yyparse()) { cerr << "Aborting." << endl; exit(1); } return parsed_scene_node; } void errFunc(const char * str, YYLTYPE * yyllocp) { fprintf(stderr, "error: %s: line %d, column %d\n", str, yyllocp->first_line, yyllocp->first_column); }