/* The geo2bog Yacc/Bison spesification file */ %{ #define YYPARSER /* distinguishes yacc output from other code files */ #include "globals.h" #include "parse.h" #include "util.h" #define YYSTYPE TreeNode_t * static TreeNode_t * savedTree; /* Stores syntax tree for later return */ %} %token GEO FILEVERSION GEOMETRY VERTEXLIST NORMALLIST TEXCOORDLIST POLYGON %token TYPE MATERIAL VERTEX NORMAL TEXCOORD NAME %token TRIANGLES QUADS QUAD_STRIP TRIANGLE_STRIP TRIANGLE_FAN %token ASSIGN FLOAT NUM STRING %token ERROR %% goeFile: geoHead geometry_seq { savedTree = newFile($1,$2); } | geometry_seq { savedTree = newFile(NULL,$1); } ; geoHead: GEO '(' FILEVERSION ASSIGN float_num ')' { $$ = newHead($5); } ; geometry_seq: geometry_seq geometry { $$ = linkNode($1,$2); } | geometry { $$ = $1; } ; geometry: GEOMETRY '{' list_seq poly_seq '}' { $$ = newGeometry($3,$4); } | GEOMETRY '(' NAME ASSIGN STRING ')' '{' list_seq poly_seq '}' { $$ = newGeometry($8,$9); } ; list_seq: list_seq list { $$ = linkNode($1,$2); } | list { $$ = $1; } ; list: vertexlist ';' { $$ = $1; } | normallist ';' { $$ = $1; } | texcoordlist ';' { $$ = $1; } ; vertexlist: VERTEXLIST ASSIGN '[' vertex_seq ']' { $$ = newVertexList($4); } ; vertex_seq: vertex_seq ',' vertex { $$ = linkNode($1,$3); } | vertex { $$ = $1; } ; vertex: '(' float_num ',' float_num ',' float_num ')' { $$ = newVertex($2,$4,$6); } ; float_num: FLOAT { $$ = newFloat((float)atof(tokenString)); } | NUM { $$ = newFloat((float)atof(tokenString)); } ; normallist: NORMALLIST ASSIGN '[' normal_seq ']' { $$ = newNormalList($4); } ; normal_seq: normal_seq ',' normal { $$ = linkNode($1,$3); } | normal { $$ = $1; } ; normal: '(' float_num ',' float_num ',' float_num ')' { $$ = newNormal($2,$4,$6); } ; texcoordlist: TEXCOORDLIST ASSIGN '[' texcoord_seq ']' { $$ = newTexCoordList($4); } ; texcoord_seq: texcoord_seq ',' texcoord { $$ = linkNode($1,$3); } | texcoord { $$ = $1; } ; texcoord: '(' float_num ',' float_num ')' { $$ = newTexCoord($2,$4); } ; poly_seq: poly_seq poly { $$ = linkNode($1,$2); } | poly { $$ = $1; } ; poly: POLYGON '{' polyattrib_seq '}' { $$ = newPoly($3); } ; polyattrib_seq : polyattrib_seq polyattrib { $$ = linkNode($1,$2); } | polyattrib { $$ = $1; } ; polyattrib: type ';' { $$ = $1; } | material ';' { $$ = $1; } | vertexindexlst ';' { $$ = $1; } | normalindexlst ';' { $$ = $1; } | texindexlst ';' { $$ = $1; } ; type: TYPE ASSIGN polytype { $$ = $3; } ; polytype: POLYGON { $$ = newPolyType(PT_Polygon); } | TRIANGLES { $$ = newPolyType(PT_Triangles); } | QUADS { $$ = newPolyType(PT_Quads); } | QUAD_STRIP { $$ = newPolyType(PT_Quad_strip); } | TRIANGLE_STRIP { $$ = newPolyType(PT_Triangle_strip); } | TRIANGLE_FAN { $$ = newPolyType(PT_Triangle_fan); } ; material: MATERIAL ASSIGN STRING { tokenString[strlen(tokenString)-1] = '\0'; $$ = newMaterial(copyString(tokenString+1)); } ; vertexindexlst: VERTEX ASSIGN '[' vertexindexseq ']' { $$ = newVertexIndexList($4); } ; vertexindexseq: vertexindexseq ',' vertexindex { $$ = linkNode($1,$3); } | vertexindex { $$ = $1; } ; vertexindex: index { $$ = $1; } ; normalindexlst: NORMAL ASSIGN '[' normalindexseq ']' { $$ = newNormalIndexList($4); } ; normalindexseq: normalindexseq ',' normalindex { $$ = linkNode($1,$3); } | normalindex { $$ = $1; } ; normalindex: index { $$ = $1; } ; texindexlst: TEXCOORD ASSIGN '[' texindexseq ']' { $$ = newTexCoordIndexList($4); } ; texindexseq: texindexseq ',' texindex { $$ = linkNode($1,$3); } | texindex { $$ = $1; } ; texindex: index { $$ = $1; } ; index: NUM { $$ = newIndex(atoi(tokenString)); } ; %% static TokenType yylex(){ return getToken(); } int yyerror(char * message){ printf("Syntax error at line %d: %s\n",lineno,message); return 0; } TreeNode_t * parse(){ yyparse(); return savedTree; }