fart/parser/parser.yy
2009-02-10 01:09:07 +00:00

254 lines
4.7 KiB
Plaintext

%{
#include <stdio.h>
#include <iostream>
#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();
~Node();
int type;
double * the_double;
Material * the_Material;
Shape * the_Shape;
Vector * the_Vector;
};
static Scene * g_scene;
#define YYSTYPE refptr<Node>
%}
%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: /* empty */
| scene_spec { printf("Saw a scene\n"); }
;
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
;
camera: CAMERA LCURLY camera_items RCURLY
;
camera_items: /* empty */
| camera_item camera_items
;
camera_item: POSITION vector
| LOOKAT vector
| UP vector
| VFOV vector
;
intersect: INTERSECT LCURLY boolean_items RCURLY
;
material: MATERIAL LCURLY material_items RCURLY
;
material_items: /* empty */
| material_item material_items
;
material_item: COLOR vector
| REFLECTANCE number
| SHININESS number
;
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;
}
;
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
;
scene_spec: SCENE LCURLY scene_items RCURLY
;
scene_items: /* empty */
| scene_item scene_items
;
scene_item: camera { $$ = $1; }
| shape { $$ = $1; }
;
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
;
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] = * (double *) $2->the_double;
(*ptr)[1] = * (double *) $4->the_double;
(*ptr)[2] = * (double *) $6->the_double;
$$ = new Node();
$$->the_Vector = ptr;
}
;
%%
int parse(Scene * scene, const char * fileName)
{
g_scene = scene;
yyin = fopen(fileName, "r");
if (yyin == NULL)
{
cerr << "Failed to open file '" << fileName << "'" << endl;
return -1;
}
yyparse();
}
Node::Node()
{
type = -1;
the_double = NULL;
the_Material = NULL;
the_Shape = NULL;
the_Vector = NULL;
}
Node::~Node()
{
if (the_double != NULL)
delete the_double;
if (the_Material != NULL)
delete the_Material;
if (the_Shape != NULL)
delete the_Shape;
if (the_Vector != NULL)
delete the_Vector;
}