fart/parser/parser.yy
Josh Holtrop c136bda827 added the_Color to Node, material gathering AMBIENT, DIFFUSE, SPECULAR color values
git-svn-id: svn://anubis/fart/trunk@103 7f9b0f55-74a9-4bce-be96-3c2cd072584d
2009-02-12 03:07:22 +00:00

363 lines
8.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();
int type;
refptr<double> the_double;
refptr<Node> the_Node;
refptr<Node> the_tail;
refptr<Material> the_Material;
refptr<Shape> the_Shape;
refptr<Vector> the_Vector;
refptr<Color> the_Color;
};
enum Node_Type
{
Node_Shape = 0x42001, /* don't clash with bison token namespace */
Node_Camera,
Node_Options
};
#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 AMBIENT;
%token BOX;
%token CAMERA;
%token DIFFUSE;
%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 SPECULAR;
%token SPHERE;
%token SUBTRACT;
%token UNION;
%token UP;
%token VFOV;
%token WIDTH;
%%
scene: SCENE LCURLY scene_items RCURLY {
refptr<Node> node = $3;
while ( ! node.isNull() )
{
/* process this scene item */
refptr<Node> thisNode = node->the_Node;
node = node->the_tail;
}
}
;
boolean_items: shape shape boolean_items_more {
$$ = new Node();
$$->the_Node = $1;
$$->the_tail = new Node();
$$->the_tail->the_Node = $2;
$$->the_tail->the_tail = new Node();
$$->the_tail->the_tail->the_Node = $3;
}
;
boolean_items_more: /* empty */
| material boolean_items_more
;
box: BOX LPAREN vector RPAREN LCURLY box_items RCURLY
;
box_items: shape_items { $$ = $1; }
;
camera: CAMERA LCURLY camera_items RCURLY {
Vector default_position(0, -1, 0);
Vector default_look_at(0, 0, 0);
Vector default_up(0, 0, 1);
}
;
camera_items: /* empty */
| camera_item camera_items
;
camera_item: POSITION vector {
$$ = new Node();
$$->type = POSITION;
$$->the_Vector = $2->the_Vector;
}
| LOOKAT vector {
$$ = new Node();
$$->type = LOOKAT;
$$->the_Vector = $2->the_Vector;
}
| UP vector {
$$ = new Node();
$$->type = UP;
$$->the_Vector = $2->the_Vector;
}
| VFOV vector {
$$ = new Node();
$$->type = VFOV;
$$->the_Vector = $2->the_Vector;
}
;
intersect: INTERSECT LCURLY boolean_items RCURLY
;
material: MATERIAL LCURLY material_items RCURLY {
$$ = new Node();
refptr<Material> material = new Material();
refptr<Node> node = $3;
while ( ! node.isNull() )
{
switch (node->type)
{
case AMBIENT:
material->setAmbientColor(*node->the_Color);
break;
case DIFFUSE:
material->setDiffuseColor(* node->the_Color);
break;
case SPECULAR:
material->setSpecularColor(* node->the_Color);
break;
case SHININESS:
material->setShininess(* node->the_double);
break;
case REFLECTANCE:
material->setReflectance(* node->the_double);
break;
}
node = node->the_Node;
}
}
;
material_items: /* empty */
| material_item material_items {
$$ = new Node();
$$->the_Node = $1;
$$->the_tail = $2;
}
;
material_item: AMBIENT vector {
$$ = new Node();
$$->type = AMBIENT;
$$->the_Color = new Color(* $2->the_Vector);
}
| DIFFUSE vector {
$$ = new Node();
$$->type = DIFFUSE;
$$->the_Color = new Color(* $2->the_Vector);
}
| SPECULAR vector {
$$ = new Node();
$$->type = SPECULAR;
$$->the_Color = new Color(* $2->the_Vector);
}
| REFLECTANCE number {
$$ = new Node();
$$->type = REFLECTANCE;
$$->the_double = $2->the_double;
}
| SHININESS number {
$$ = new Node();
$$->type = SHININESS;
$$->the_double = $2->the_double;
}
;
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;
}
;
options: OPTIONS LCURLY options_items RCURLY { $$ = $3; }
;
options_items: /* empty */
| options_item options_items {
$$ = new Node();
$$->the_Node = $1;
$$->the_tail = $2;
}
;
options_item: WIDTH number {
$$ = new Node();
$$->type = WIDTH;
$$->the_double = $2->the_double;
}
| HEIGHT number {
$$ = new Node();
$$->type = HEIGHT;
$$->the_double = $2->the_double;
}
| MULTISAMPLE number {
$$ = new Node();
$$->type = MULTISAMPLE;
$$->the_double = $2->the_double;
}
;
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 { $$ = $1; }
;
scene_items: /* empty */
| scene_item scene_items {
$$ = new Node();
$$->the_Node = $1;
$$->the_tail = $2;
}
;
scene_item: camera { $$ = $1; $$->type = Node_Camera; }
| shape { $$ = $1; $$->type = Node_Shape; }
| options { $$ = $1; $$->type = Node_Options; }
;
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 { $$ = $1; }
;
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] = * $2->the_double;
(*ptr)[1] = * $4->the_double;
(*ptr)[2] = * $6->the_double;
$$ = new Node();
$$->the_Vector = ptr;
}
;
%%
int Scene::parse(const char * fileName)
{
yyin = fopen(fileName, "r");
if (yyin == NULL)
{
cerr << "Failed to open file '" << fileName << "'" << endl;
return -1;
}
yyparse();
return 0;
}
Node::Node()
{
type = -1;
}