%{ #include #include #include "util/Vector.h" #include "util/refptr.h" #include "util/Scope.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; refptr parser_scope; %} %pure-parser %locations %error-verbose %token PLUS; %token MINUS; %token TIMES; %token DIVIDE; %token MOD; %token POW; %token ASSIGN; %token EQUALS; %token NOTEQUALS; %token LESS; %token LESSEQ; %token GREATER; %token GREATEREQ; %token AND %token OR %token NOT; %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 REAL_NUMBER; %token AMBIENT; %token AMBIENT_OCCLUSION; %token BOX; %token CAMERA; %token COLOR; %token CYL; %token DEFINE; %token DIFFUSE; %token EXPOSURE; %token EXTRUDE; %token HEIGHT; %token INTERSECT; %token JITTER; %token LIGHT; %token LOOKAT; %token MATERIAL; %token MAXDEPTH; %token MULTISAMPLE; %token NGON; %token OFFSET; %token OPTIONS; %token PLANE; %token POLYGON; %token POSITION; %token RADIUS; %token REFLECTANCE; %token ROTATE; %token SCALE; %token SCENE; %token SHAPE; %token SHININESS; %token SIZE; %token SPECULAR; %token SPHERE; %token SUBTRACT; %token TRANSLATE; %token TRANSPARENCY; %token UNION; %token UP; %token VFOV; %token WIDTH; %token IDENTIFIER; %token VARREF; %token ELSE; %token ELSIF; %token FOR; %token IF; %token WHILE; %token LOCAL; %right ASSIGN %left AND OR NOT %left PLUS MINUS %left TIMES DIVIDE MOD %right POW %left UMINUS %% scene: SCENE LCURLY general_items RCURLY { $$ = new SceneNode(); $$->addChildren($3); parsed_scene_node = $$; } ; box: BOX LCURLY general_items RCURLY { $$ = new BoxNode(); $$->addChildren($3); } ; camera: CAMERA LCURLY general_items RCURLY { $$ = new CameraNode(); $$->addChildren($3); } ; cyl: CYL LCURLY general_items RCURLY { $$ = new CylNode(); $$->addChildren($3); } ; extrude: EXTRUDE LCURLY general_items RCURLY { $$ = new ExtrudeNode(); $$->addChildren($3); } ; general_items: /* empty */ | general_item general_items { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; general_item: AMBIENT vector3 { $$ = new AmbientNode($2); } | AMBIENT_OCCLUSION expression { $$ = new AmbientOcclusionNode($2); } | camera { $$ = $1; } | COLOR vector3 { $$ = new ColorNode($2); } | DIFFUSE vector3 { $$ = new DiffuseNode($2); } | EXPOSURE expression { $$ = new ExposureNode($2); } | for { $$ = $1; } | HEIGHT expression { $$ = new HeightNode($2); } | if { $$ = $1; } | JITTER expression { $$ = new JitterNode($2); } | light { $$ = $1; } | LOOKAT vector3 { $$ = new LookAtNode($2); } | material { $$ = $1; } | material_definition { $$ = $1; } | material_ref { $$ = $1; } | MAXDEPTH expression { $$ = new MaxDepthNode($2); } | MULTISAMPLE expression { $$ = new MultisampleNode($2); } | ngon { $$ = $1; } | offset { $$ = $1; } | options { $$ = $1; } | polygon { $$ = $1; } | POSITION vector3 { $$ = new PositionNode($2); } | POSITION vector3 COMMA expression { $$ = new PlanePositionNode($2, $4); } | RADIUS expression { $$ = new RadiusNode($2); } | REFLECTANCE expression { $$ = new ReflectanceNode($2); } | ROTATE expression COMMA vector3 { $$ = new RotateNode($2, $4); } | SCALE expression { $$ = new ScaleNode(new ScaleScalarNode($2)); } | SCALE vector2 { $$ = new ScaleNode($2); } | SCALE vector3 { $$ = new ScaleNode($2); } | shape { $$ = $1; } | shape_definition { $$ = $1; } | SHININESS expression { $$ = new ShininessNode($2); } | SIZE vector3 { $$ = new SizeNode($2); } | SPECULAR vector3 { $$ = new SpecularNode($2); } | stmt_expression { $$ = $1; } | transform_block { $$ = $1; } | TRANSLATE vector3 { $$ = new TranslateNode($2); } | TRANSPARENCY expression { $$ = new TransparencyNode($2); } | UP vector3 { $$ = new UpNode($2); } | vector2 { $$ = $1; } | VFOV expression { $$ = new VFOVNode($2); } | WIDTH expression { $$ = new WidthNode($2); } ; intersect: INTERSECT LCURLY general_items RCURLY { $$ = new IntersectNode(); $$->addChildren($3); } ; light: LIGHT LCURLY general_items RCURLY { $$ = new LightNode(); $$->addChildren($3); } ; material: MATERIAL LCURLY general_items RCURLY { $$ = new MaterialNode(); $$->addChildren($3); } ; material_definition: DEFINE MATERIAL IDENTIFIER LCURLY general_items RCURLY { $$ = new MaterialDefinitionNode($3->getString()); $$->addChildren($5); } ; material_ref: MATERIAL IDENTIFIER { $$ = new MaterialRefNode($2->getString()); } ; number: REAL_NUMBER { $$ = $1; } ; ngon: NGON expression COMMA expression { $$ = new NGonNode($2); $$->addChild(new RadiusNode($4)); } ; offset: OFFSET expression { $$ = new OffsetNode($2); } | OFFSET expression LCURLY general_items RCURLY { $$ = new OffsetNode($2); $$->addChildren($4); } ; options: OPTIONS LCURLY general_items RCURLY { $$ = new OptionsNode(); $$->addChildren($3); } ; plane: PLANE LCURLY general_items RCURLY { $$ = new PlaneNode(); $$->addChildren($3); } ; polygon: POLYGON LCURLY general_items RCURLY { $$ = new PolygonNode(); $$->addChildren($3); } ; shape: plane { $$ = $1; } | sphere { $$ = $1; } | box { $$ = $1; } | cyl { $$ = $1; } | union { $$ = $1; } | intersect { $$ = $1; } | subtract { $$ = $1; } | extrude { $$ = $1; } | shape_ref { $$ = $1; } ; shape_definition: DEFINE SHAPE IDENTIFIER shape { $$ = new ShapeDefinitionNode($3->getString()); $$->addChild($4); } ; shape_ref: SHAPE IDENTIFIER shape_ref_more { $$ = new ShapeRefNode($2->getString()); $$->addChildren($3); } ; shape_ref_more: /* empty */ | LCURLY general_items RCURLY { $$ = $2; } ; sphere: SPHERE LCURLY general_items RCURLY { $$ = new SphereNode(); $$->addChildren($3); } ; subtract: SUBTRACT LCURLY general_items RCURLY { $$ = new SubtractNode(); $$->addChildren($3); } ; transform_block: TRANSLATE vector3 LCURLY general_items RCURLY { $$ = new TranslateBlockNode($2); $$->addChildren($4); } | ROTATE expression COMMA vector3 LCURLY general_items RCURLY { $$ = new RotateBlockNode($2, $4); $$->addChildren($6); } | SCALE vector3 LCURLY general_items RCURLY { $$ = new ScaleBlockNode($2); $$->addChildren($4); } | SCALE expression LCURLY general_items RCURLY { $$ = new ScaleBlockNode(new ScaleScalarNode($2)); $$->addChildren($4); } ; union: UNION LCURLY general_items RCURLY { $$ = new UnionNode(); $$->addChildren($3); } ; vector2: LESS expression COMMA expression GREATER { $$ = new VectorNode($2, $4, new NumberNode(0.0)); } ; vector3: LESS expression COMMA expression COMMA expression GREATER { $$ = new VectorNode($2, $4, $6); } ; expression: expression TIMES expression { $$ = new BinOpNode('*', $1, $3); } | expression DIVIDE expression { $$ = new BinOpNode('/', $1, $3); } | expression PLUS expression { $$ = new BinOpNode('+', $1, $3); } | expression MINUS expression { $$ = new BinOpNode('-', $1, $3); } | expression MOD expression { $$ = new BinOpNode('%', $1, $3); } | expression POW expression { $$ = new BinOpNode('^', $1, $3); } | MINUS expression %prec UMINUS { $$ = new BinOpNode('-', new NumberNode(0.0), $2); } | stmt_expression { $$ = $1; } | function_call { $$ = $1; } | number { $$ = $1; } | VARREF { $$ = $1; } | LPAREN expression RPAREN { $$ = $2; } ; maybe_expression: /* empty */ | expression { $$ = $1; } ; stmt_expression: assignment { $$ = $1; } | local_assignment { $$ = $1; } | local_decl { $$ = $1; } ; bool_expression: expression LESS expression { $$ = new BoolExpressionNode('<', $1, $3); } | expression LESSEQ expression { $$ = new BoolExpressionNode('l', $1, $3); } | expression GREATER expression { $$ = new BoolExpressionNode('>', $1, $3); } | expression GREATEREQ expression { $$ = new BoolExpressionNode('g', $1, $3); } | expression EQUALS expression { $$ = new BoolExpressionNode('=', $1, $3); } | expression NOTEQUALS expression { $$ = new BoolExpressionNode('n', $1, $3); } | bool_expression AND bool_expression { $$ = new BoolExpressionNode('&', $1, $3); } | bool_expression OR bool_expression { $$ = new BoolExpressionNode('|', $1, $3); } | NOT bool_expression { $$ = new BoolExpressionNode('!', $2, NULL); } ; assignment: VARREF ASSIGN expression { $$ = new AssignmentNode($1, $3); } ; local_assignment: LOCAL VARREF ASSIGN expression { $$ = new LocalAssignmentNode($2, $4); } ; local_decl: LOCAL VARREF { $$ = new LocalDeclNode($2); } ; for: FOR LPAREN maybe_expression SEMICOLON bool_expression SEMICOLON maybe_expression RPAREN LCURLY general_items RCURLY { $$ = new ForNode($3, $5, $7); $$->addChildren($10); } ; if: IF LPAREN bool_expression RPAREN LCURLY general_items RCURLY if_more { $$ = new IfNode($3, $8); $$->addChildren($6); } ; if_more: /* empty */ | ELSIF LPAREN bool_expression RPAREN LCURLY general_items RCURLY if_more { $$ = new IfNode($3, $8); $$->addChildren($6); } | ELSE LCURLY general_items RCURLY { $$ = new ElseNode(); $$->addChildren($3); } ; function_call: IDENTIFIER LPAREN function_call_parameters RPAREN { $$ = new FunctionCallNode($1, $3); } ; function_call_parameters: /* empty */ | expression function_call_more_parameters { $$ = new ItemsNode(); $$->addChild($1); $$->addChildren($2); } ; function_call_more_parameters: /* empty */ | COMMA expression function_call_more_parameters { $$ = new ItemsNode(); $$->addChild($2); $$->addChildren($3); } ; %% refptr parse(const char * fileName, refptr scope) { parser_scope = scope; 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); }