/* * Purpose: This module parses the .obj file. It gets tokens * from the lexer (obj_lex.l), checks the grammar and * calls the appropriate routines from database.c * * Use yacc or bison to convert this module into C source and * then compile normally. * * Notes: - uses external variables declared below * * Modified version of Sam Samai's o2r_gram.y * * Updated: 25/4/95 */ %{ #ifdef DEBUG #define DBG(s) s #else #define DBG(s) #endif #include "collDetect.h" #include "database.h" #include extern ObjNode *envObjs; extern Boolean new_face; extern int lineno; %} %union { double y_scl; int y_num; char * y_str; } /* Terminal Symbols */ %token Identifier %token Const %token String %token '$' %token '(' %token ')' %token '/' /* Reserved Words */ %token Bevel Bezier Bias_mat Bmatrix Bspline %token C_interp Call Cardinal Comment Con Csh Cstype Ctech Curve Curve2 %token D_interp Deg %token End %token Face %token Group %token Hole %token Line Level_o_detail %token Merge_group Mtllib %token Object_name %token Point Parm_values %token Rat Ray_object %token Smooth_group Scmp Scrv Shadow_obj Special_pt Stech Step Surface %token Taylor Trace_obj Trim %token Usemtl U_p %token V Vtx_normal Vtx_parameter Vtx_texture /* typed non-terminal symbols */ %type optional_const /* precedence table */ %% items : /* empty */ { } | items {lineno++;} item ; item : vertex | vertex_norm | vertex_texture | face | point | line | material_lib | material | smooth | group | object_name | comment | ray_object ; vertex : V Const Const Const { Tupple vt; vt.i = $2; vt.j = $3; vt.k = $4; DBG(printf("Found a vertex! : ");) addTupple(vt, &(envObjs->va)); } ; vertex_norm : Vtx_normal Const Const Const { Tupple vn; vn.i = $2; vn.j = $3; vn.k = $4; DBG(printf("Found a vertex normal! : ");) addTupple(vn, &(envObjs->vn)); } ; vertex_texture: Vtx_texture Const Const { DBG(printf("Found a texture vertex! (2 params): ");) } | Vtx_texture Const Const Const { DBG(printf("Found a texture vertex! (3 params): ");) } ; face: Face { new_face = True; DBG(printf("face:\n");) } index_list { } ; line: Line { DBG(printf("/* l ");) new_face = True; } index_list { DBG(printf("*/\n");) } ; point : Point { DBG(printf("/* p ");) } index_list { DBG(printf("*/\n");) } ; index_list: index index_list | index ; index: Const '/' optional_const '/' Const { /* * vertex/texture/normal or vertex//normal * --> triangleuv or triangle */ DBG(printf("%f/%f/%f\n", $1, $3, $5);) obj_face(envObjs, (int)$1, (int)$5); } | Const '/' Const { /* * vertex/texture --> triangleuv, norm = 0 */ DBG(printf("index: vertex/texture_vertex : ");) DBG(printf("%f/%f\n", $1, $3);) obj_face(envObjs, (int)$1, 0); } | Const { /* * vertex --> poly */ DBG(printf("index: vertex : ");) DBG(printf("%f\n", $1);) obj_face(envObjs, (int)$1, 0); } ; optional_const: { $$ = 0.0; DBG(printf("vertex//normal : ");) } /* empty */ | Const { $$ = $1; DBG(printf("vertex/texture_vertex/normal : ");) } ; material_lib : Mtllib Identifier { DBG(printf("Material Lib: %s\n", $2);) } ; material : Usemtl Identifier { DBG(printf("Material: %s\n", $2);) } ; smooth : Smooth_group Identifier | Smooth_group Const { DBG(printf("Found a smoothing group statement!\n");) } ; group : Group opt_identifiers { DBG(printf("Found a group\n");) } ; comment : Comment { DBG(printf("/* ");) } strings { DBG(printf("*/\n");) } ; strings: | strings Identifier { DBG(printf("%s ", ($2));) } | strings Const { DBG(printf(" %f", ($2));) } ; opt_identifiers: /* empty */ { } /* | Identifier opt_identifiers */ | Identifier { DBG(printf(" %s", $1);) } opt_identifiers { } ; object_name: Object_name { DBG(printf("/*o ");) Tupple trans; new_face = True; if (envObjs->polys.total != 0) { /* check that the current head of the object list isn't empty, * ie. it has polygons etc and is done with, so it can be * finished with and an empty ObjNode added. */ zeroObject(envObjs, &trans); /* zeroObject moves the object such that it lies in the positive * octant in its own reference frame. trans is needed in case * the object was read with reference to the global frame, and * so we can then create the required transform to put it in * the global frame. */ calcObjInfo(envObjs); envObjs = addEmptyObjNode(envObjs); } } opt_identifiers { DBG(printf("*/\n");) } ; ray_object: Ray_object { DBG(printf("Hand coded rayshade object:\n");)} strings;