fart/parser/parser.yy
Josh Holtrop 395161eb66 parser.lex keeping track of line number now
git-svn-id: svn://anubis/fart/trunk@129 7f9b0f55-74a9-4bce-be96-3c2cd072584d
2009-02-18 02:10:27 +00:00

416 lines
9.7 KiB
Plaintext

%{
#include <stdio.h>
#include <iostream>
#include "util/Vector.h"
#include "util/refptr.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<Node> parsed_scene_node;
%}
%pure-parser
%locations
%error-verbose
%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 LIGHT;
%token LOOKAT;
%token MATERIAL;
%token MULTISAMPLE;
%token OPTIONS;
%token PLANE;
%token POSITION;
%token RADIUS;
%token REFLECTANCE;
%token ROTATE;
%token SCALE;
%token SCENE;
%token SHININESS;
%token SIZE;
%token SPECULAR;
%token SPHERE;
%token SUBTRACT;
%token TRANSLATE;
%token UNION;
%token UP;
%token VFOV;
%token WIDTH;
%%
scene: SCENE LCURLY scene_items RCURLY {
$$ = new SceneNode();
$$->addChildren($3);
parsed_scene_node = $$;
}
;
box: BOX LCURLY box_items RCURLY {
$$ = new BoxNode();
$$->addChildren($3);
}
;
box_items: /* empty */
| box_item box_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
box_item: SIZE vector {
$$ = new SizeNode($2->getVector());
}
| shape_item { $$ = $1; }
;
camera: CAMERA LCURLY camera_items RCURLY {
$$ = new CameraNode();
$$->addChildren($3);
}
;
camera_items: /* empty */
| camera_item camera_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
camera_item: POSITION vector {
$$ = new PositionNode();
$$->addChild($2);
}
| LOOKAT vector {
$$ = new LookAtNode();
$$->addChild($2);
}
| UP vector {
$$ = new UpNode();
$$->addChild($2);
}
| VFOV vector {
$$ = new VFOVNode();
$$->addChild($2);
}
;
intersect: INTERSECT LCURLY shape shape shape_items RCURLY {
$$ = new IntersectNode();
$$->addChild($3);
$$->addChild($4);
$$->addChildren($5);
}
;
light: LIGHT LCURLY light_items RCURLY {
$$ = new LightNode();
$$->addChildren($3);
}
;
light_items: /* empty */
| light_item light_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
light_item: POSITION vector {
$$ = new PositionNode();
$$->addChild($2);
}
| DIFFUSE vector {
$$ = new DiffuseNode();
$$->addChild($2);
}
| SPECULAR vector {
$$ = new SpecularNode();
$$->addChild($2);
}
;
material: MATERIAL LCURLY material_items RCURLY {
$$ = new MaterialNode();
$$->addChildren($3);
}
;
material_items: /* empty */
| material_item material_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
material_item: AMBIENT vector {
$$ = new AmbientNode();
$$->addChild($2);
}
| DIFFUSE vector {
$$ = new DiffuseNode();
$$->addChild($2);
}
| SPECULAR vector {
$$ = new SpecularNode();
$$->addChild($2);
}
| REFLECTANCE number {
$$ = new ReflectanceNode($2->getNumber());
}
| SHININESS number {
$$ = new ShininessNode($2->getNumber());
}
;
number: DEC_NUMBER { $$ = $1; }
| REAL_NUMBER { $$ = $1; }
;
options: OPTIONS LCURLY options_items RCURLY {
$$ = new OptionsNode();
$$->addChildren($3);
}
;
options_items: /* empty */
| options_item options_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
options_item: WIDTH DEC_NUMBER {
$$ = new WidthNode($2->getInteger());
}
| HEIGHT DEC_NUMBER {
$$ = new HeightNode($2->getInteger());
}
| MULTISAMPLE DEC_NUMBER {
$$ = new MultisampleNode($2->getInteger());
}
;
plane: PLANE LCURLY plane_items RCURLY {
$$ = new PlaneNode();
$$->addChildren($3);
}
;
plane_items: /* empty */
| plane_item plane_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
plane_item: POSITION vector COMMA number {
$$ = new PlanePositionNode($2->getVector(), $4->getNumber());
}
| shape_item { $$ = $1; }
;
radius: RADIUS number {
$$ = new RadiusNode($2->getNumber());
}
;
scene_items: /* empty */
| scene_item scene_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
scene_item: camera { $$ = $1; }
| shape { $$ = $1; }
| options { $$ = $1; }
| light { $$ = $1; }
| transform_block { $$ = $1; }
;
shape: plane { $$ = $1; }
| sphere { $$ = $1; }
| box { $$ = $1; }
| union { $$ = $1; }
| intersect { $$ = $1; }
| subtract { $$ = $1; }
;
shape_items: /* empty */
| shape_item shape_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
shape_item: material { $$ = $1; }
| transform { $$ = $1; }
;
sphere: SPHERE LCURLY sphere_items RCURLY {
$$ = new SphereNode();
$$->addChild($3);
}
;
sphere_items: /* empty */
| sphere_item sphere_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
sphere_item: radius { $$ = $1; }
| shape_item { $$ = $1; }
;
subtract: SUBTRACT LCURLY shape shape shape_items RCURLY {
$$ = new SubtractNode();
$$->addChild($3);
$$->addChild($4);
$$->addChildren($5);
}
;
transform: TRANSLATE vector {
$$ = new TranslateNode($2->getVector());
}
| ROTATE number COMMA vector {
$$ = new RotateNode($2->getNumber(), $4->getVector());
}
| SCALE vector {
$$ = new ScaleNode($2->getVector());
}
;
transform_block: TRANSLATE vector LCURLY transform_block_items RCURLY {
$$ = new TranslateBlockNode($2->getVector());
$$->addChildren($4);
}
| ROTATE number COMMA vector LCURLY transform_block_items RCURLY {
$$ = new RotateBlockNode($2->getNumber(), $4->getVector());
$$->addChildren($6);
}
| SCALE vector LCURLY transform_block_items RCURLY {
$$ = new ScaleBlockNode($2->getVector());
$$->addChildren($4);
}
;
transform_block_items: /* empty */
| transform_block_item transform_block_items {
$$ = new ItemsNode();
$$->addChild($1);
$$->addChildren($2);
}
;
transform_block_item: transform_block { $$ = $1; }
| light { $$ = $1; }
| shape { $$ = $1; }
;
union: UNION LCURLY shape shape shape_items RCURLY {
$$ = new UnionNode();
$$->addChild($3);
$$->addChild($4);
$$->addChildren($5);
}
;
vector: LESS number COMMA number COMMA number GREATER {
refptr<Vector> vec = new Vector();
(*vec)[0] = $2->getNumber();
(*vec)[1] = $4->getNumber();
(*vec)[2] = $6->getNumber();
$$ = new VectorNode(vec);
}
;
%%
refptr<Node> parse(const char * fileName)
{
yyin = fopen(fileName, "r");
if (yyin == NULL)
{
cerr << "Failed to open file '" << fileName << "'" << endl;
return refptr<Node>(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);
}