git-svn-id: svn://anubis/fart/branches/scene-file-scripting@337 7f9b0f55-74a9-4bce-be96-3c2cd072584d
678 lines
16 KiB
Plaintext
678 lines
16 KiB
Plaintext
|
|
%{
|
|
|
|
#include <stdio.h>
|
|
#include <iostream>
|
|
#include "util/Vector.h"
|
|
#include "util/refptr.h"
|
|
#include "util/Scope.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;
|
|
refptr<Scope> parser_scope;
|
|
|
|
%}
|
|
|
|
%pure-parser
|
|
%locations
|
|
%error-verbose
|
|
|
|
%token PLUS;
|
|
%token MINUS;
|
|
%token TIMES;
|
|
%token DIVIDE;
|
|
%token MOD;
|
|
%token ASSIGN;
|
|
%token EQUALS;
|
|
%token NOTEQUALS;
|
|
%token NOT;
|
|
|
|
%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 REAL_NUMBER;
|
|
|
|
%token AMBIENT;
|
|
%token AMBIENT_OCCLUSION;
|
|
%token BOX;
|
|
%token CAMERA;
|
|
%token COLOR;
|
|
%token CYL;
|
|
%token DEFINE;
|
|
%token DIFFUSE;
|
|
%token EXPOSURE;
|
|
%token EXTRUDE;
|
|
%token HEIGHT;
|
|
%token INTERSECT;
|
|
%token JITTER;
|
|
%token LIGHT;
|
|
%token LOOKAT;
|
|
%token MATERIAL;
|
|
%token MAXDEPTH;
|
|
%token MULTISAMPLE;
|
|
%token NGON;
|
|
%token OFFSET;
|
|
%token OPTIONS;
|
|
%token PLANE;
|
|
%token POLYGON;
|
|
%token POSITION;
|
|
%token RADIUS;
|
|
%token REFLECTANCE;
|
|
%token ROTATE;
|
|
%token SCALE;
|
|
%token SCENE;
|
|
%token SHAPE;
|
|
%token SHININESS;
|
|
%token SIZE;
|
|
%token SPECULAR;
|
|
%token SPHERE;
|
|
%token SUBTRACT;
|
|
%token TRANSLATE;
|
|
%token TRANSPARENCY;
|
|
%token UNION;
|
|
%token UP;
|
|
%token VFOV;
|
|
%token WIDTH;
|
|
|
|
%token IDENTIFIER;
|
|
%token VARREF;
|
|
|
|
%token ELSE;
|
|
%token ELSIF;
|
|
%token FOR;
|
|
%token IF;
|
|
%token WHILE;
|
|
%token LOCAL;
|
|
|
|
%right ASSIGN
|
|
%left PLUS MINUS
|
|
%left TIMES DIVIDE
|
|
%left UMINUS
|
|
|
|
%%
|
|
|
|
scene: SCENE LCURLY scene_items RCURLY {
|
|
$$ = new SceneNode();
|
|
$$->addChildren($3);
|
|
parsed_scene_node = $$;
|
|
}
|
|
;
|
|
|
|
bool_items: /* empty */
|
|
| bool_item bool_items {
|
|
$$ = new ItemsNode();
|
|
$$->addChild($1);
|
|
$$->addChildren($2);
|
|
}
|
|
;
|
|
|
|
bool_item: shape
|
|
| shape_item
|
|
| shape_definition
|
|
| transform_block
|
|
;
|
|
|
|
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 vector3 {
|
|
$$ = new SizeNode($2);
|
|
}
|
|
| 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 vector3 {
|
|
$$ = new PositionNode($2);
|
|
}
|
|
| LOOKAT vector3 {
|
|
$$ = new LookAtNode($2);
|
|
}
|
|
| UP vector3 {
|
|
$$ = new UpNode($2);
|
|
}
|
|
| VFOV expression {
|
|
$$ = new VFOVNode($2);
|
|
}
|
|
;
|
|
|
|
cyl: CYL LCURLY cyl_items RCURLY {
|
|
$$ = new CylNode();
|
|
$$->addChildren($3);
|
|
}
|
|
;
|
|
|
|
cyl_items: /* empty */
|
|
| cyl_item cyl_items {
|
|
$$ = new ItemsNode();
|
|
$$->addChild($1);
|
|
$$->addChildren($2);
|
|
}
|
|
;
|
|
|
|
cyl_item: SIZE vector3 {
|
|
$$ = new SizeNode($2);
|
|
}
|
|
| shape_item { $$ = $1; }
|
|
;
|
|
|
|
extrude: EXTRUDE LCURLY extrude_items RCURLY {
|
|
$$ = new ExtrudeNode();
|
|
$$->addChildren($3);
|
|
}
|
|
;
|
|
|
|
extrude_items: /* empty */
|
|
| extrude_item extrude_items {
|
|
$$ = new ItemsNode();
|
|
$$->addChild($1);
|
|
$$->addChildren($2);
|
|
}
|
|
;
|
|
|
|
extrude_item: polygon { $$ = $1; }
|
|
| ngon { $$ = $1; }
|
|
| offset { $$ = $1; }
|
|
| shape_item { $$ = $1; }
|
|
;
|
|
|
|
general_items: /* empty */
|
|
| general_item general_items {
|
|
$$ = new ItemsNode();
|
|
$$->addChild($1);
|
|
$$->addChildren($2);
|
|
}
|
|
;
|
|
|
|
general_item: transform_block { $$ = $1; }
|
|
| material_definition { $$ = $1; }
|
|
| shape_definition { $$ = $1; }
|
|
| shape { $$ = $1; }
|
|
| for { $$ = $1; }
|
|
| stmt_expression { $$ = $1; }
|
|
;
|
|
|
|
intersect: INTERSECT LCURLY bool_items RCURLY {
|
|
$$ = new IntersectNode();
|
|
$$->addChildren($3);
|
|
}
|
|
;
|
|
|
|
jitter: JITTER expression {
|
|
$$ = new JitterNode($2);
|
|
}
|
|
;
|
|
|
|
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 vector3 {
|
|
$$ = new PositionNode($2);
|
|
}
|
|
| DIFFUSE vector3 {
|
|
$$ = new DiffuseNode($2);
|
|
}
|
|
| SPECULAR vector3 {
|
|
$$ = new SpecularNode($2);
|
|
}
|
|
| COLOR vector3 {
|
|
$$ = new ColorNode($2);
|
|
}
|
|
| radius {
|
|
$$ = $1;
|
|
}
|
|
| jitter {
|
|
$$ = $1;
|
|
}
|
|
;
|
|
|
|
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: COLOR vector3 {
|
|
$$ = new ColorNode($2);
|
|
}
|
|
| AMBIENT vector3 {
|
|
$$ = new AmbientNode($2);
|
|
}
|
|
| DIFFUSE vector3 {
|
|
$$ = new DiffuseNode($2);
|
|
}
|
|
| SPECULAR vector3 {
|
|
$$ = new SpecularNode($2);
|
|
}
|
|
| REFLECTANCE expression {
|
|
$$ = new ReflectanceNode($2);
|
|
}
|
|
| SHININESS expression {
|
|
$$ = new ShininessNode($2);
|
|
}
|
|
| TRANSPARENCY expression {
|
|
$$ = new TransparencyNode($2);
|
|
}
|
|
;
|
|
|
|
material_definition: DEFINE MATERIAL IDENTIFIER LCURLY material_items RCURLY {
|
|
$$ = new MaterialDefinitionNode($3->getString());
|
|
$$->addChildren($5);
|
|
}
|
|
;
|
|
|
|
material_ref: MATERIAL IDENTIFIER {
|
|
$$ = new MaterialRefNode($2->getString());
|
|
}
|
|
;
|
|
|
|
number: REAL_NUMBER { $$ = $1; }
|
|
;
|
|
|
|
ngon: NGON expression COMMA expression {
|
|
$$ = new NGonNode($2);
|
|
$$->addChild(new RadiusNode($4));
|
|
}
|
|
;
|
|
|
|
offset: OFFSET expression {
|
|
$$ = new OffsetNode($2);
|
|
}
|
|
| OFFSET expression LCURLY offset_items RCURLY {
|
|
$$ = new OffsetNode($2);
|
|
$$->addChildren($4);
|
|
}
|
|
;
|
|
|
|
offset_items: /* empty */
|
|
| offset_item offset_items {
|
|
$$ = new ItemsNode();
|
|
$$->addChild($1);
|
|
$$->addChildren($2);
|
|
}
|
|
;
|
|
|
|
offset_item: SCALE expression {
|
|
$$ = new ScaleNode(new ScaleScalarNode($2));
|
|
}
|
|
| SCALE vector2 {
|
|
$$ = new ScaleNode($2);
|
|
}
|
|
| POSITION vector2 {
|
|
$$ = new PositionNode($2);
|
|
}
|
|
;
|
|
|
|
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 expression {
|
|
$$ = new WidthNode($2);
|
|
}
|
|
| HEIGHT expression {
|
|
$$ = new HeightNode($2);
|
|
}
|
|
| MULTISAMPLE expression {
|
|
$$ = new MultisampleNode($2);
|
|
}
|
|
| MAXDEPTH expression {
|
|
$$ = new MaxDepthNode($2);
|
|
}
|
|
| EXPOSURE expression {
|
|
$$ = new ExposureNode($2);
|
|
}
|
|
| AMBIENT vector3 {
|
|
$$ = new AmbientNode($2);
|
|
}
|
|
| AMBIENT_OCCLUSION expression {
|
|
$$ = new AmbientOcclusionNode($2);
|
|
}
|
|
;
|
|
|
|
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 vector3 COMMA expression {
|
|
$$ = new PlanePositionNode($2, $4);
|
|
}
|
|
| shape_item { $$ = $1; }
|
|
;
|
|
|
|
polygon: POLYGON LCURLY polygon_items RCURLY {
|
|
$$ = new PolygonNode();
|
|
$$->addChildren($3);
|
|
}
|
|
;
|
|
|
|
polygon_items: /* empty */
|
|
| polygon_item polygon_items {
|
|
$$ = new ItemsNode();
|
|
$$->addChild($1);
|
|
$$->addChildren($2);
|
|
}
|
|
;
|
|
|
|
polygon_item: vector2 { $$ = $1; }
|
|
;
|
|
|
|
radius: RADIUS expression {
|
|
$$ = new RadiusNode($2);
|
|
}
|
|
;
|
|
|
|
scene_items: /* empty */
|
|
| scene_item scene_items {
|
|
$$ = new ItemsNode();
|
|
$$->addChild($1);
|
|
$$->addChildren($2);
|
|
}
|
|
;
|
|
|
|
scene_item: camera { $$ = $1; }
|
|
| light { $$ = $1; }
|
|
| options { $$ = $1; }
|
|
| general_item { $$ = $1; }
|
|
;
|
|
|
|
shape: plane { $$ = $1; }
|
|
| sphere { $$ = $1; }
|
|
| box { $$ = $1; }
|
|
| cyl { $$ = $1; }
|
|
| union { $$ = $1; }
|
|
| intersect { $$ = $1; }
|
|
| subtract { $$ = $1; }
|
|
| extrude { $$ = $1; }
|
|
| shape_ref { $$ = $1; }
|
|
;
|
|
|
|
shape_definition: DEFINE SHAPE IDENTIFIER shape {
|
|
$$ = new ShapeDefinitionNode($3->getString());
|
|
$$->addChild($4);
|
|
}
|
|
;
|
|
|
|
shape_ref: SHAPE IDENTIFIER shape_ref_more {
|
|
$$ = new ShapeRefNode($2->getString());
|
|
$$->addChildren($3);
|
|
}
|
|
;
|
|
|
|
shape_ref_more: /* empty */
|
|
| LCURLY shape_ref_items RCURLY { $$ = $2; }
|
|
;
|
|
|
|
shape_ref_items: /* empty */
|
|
| shape_item shape_ref_items {
|
|
$$ = new ItemsNode();
|
|
$$->addChild($1);
|
|
$$->addChildren($2);
|
|
}
|
|
;
|
|
|
|
shape_item: material { $$ = $1; }
|
|
| material_ref { $$ = $1; }
|
|
| transform { $$ = $1; }
|
|
;
|
|
|
|
sphere: SPHERE LCURLY sphere_items RCURLY {
|
|
$$ = new SphereNode();
|
|
$$->addChildren($3);
|
|
}
|
|
;
|
|
|
|
sphere_items: /* empty */
|
|
| sphere_item sphere_items {
|
|
$$ = new ItemsNode();
|
|
$$->addChild($1);
|
|
$$->addChildren($2);
|
|
}
|
|
;
|
|
|
|
sphere_item: radius { $$ = $1; }
|
|
| shape_item { $$ = $1; }
|
|
;
|
|
|
|
subtract: SUBTRACT LCURLY bool_items RCURLY {
|
|
$$ = new SubtractNode();
|
|
$$->addChildren($3);
|
|
}
|
|
;
|
|
|
|
transform: TRANSLATE vector3 {
|
|
$$ = new TranslateNode($2);
|
|
}
|
|
| ROTATE expression COMMA vector3 {
|
|
$$ = new RotateNode($2, $4);
|
|
}
|
|
| SCALE vector3 {
|
|
$$ = new ScaleNode($2);
|
|
}
|
|
| SCALE expression {
|
|
$$ = new ScaleNode(new ScaleScalarNode($2));
|
|
}
|
|
;
|
|
|
|
transform_block: TRANSLATE vector3 LCURLY general_items RCURLY {
|
|
$$ = new TranslateBlockNode($2);
|
|
$$->addChildren($4);
|
|
}
|
|
| ROTATE expression COMMA vector3 LCURLY general_items RCURLY {
|
|
$$ = new RotateBlockNode($2, $4);
|
|
$$->addChildren($6);
|
|
}
|
|
| SCALE vector3 LCURLY general_items RCURLY {
|
|
$$ = new ScaleBlockNode($2);
|
|
$$->addChildren($4);
|
|
}
|
|
| SCALE expression LCURLY general_items RCURLY {
|
|
$$ = new ScaleBlockNode(new ScaleScalarNode($2));
|
|
$$->addChildren($4);
|
|
}
|
|
;
|
|
|
|
union: UNION LCURLY bool_items RCURLY {
|
|
$$ = new UnionNode();
|
|
$$->addChildren($3);
|
|
}
|
|
;
|
|
|
|
vector2: LESS expression COMMA expression GREATER {
|
|
$$ = new VectorNode($2, $4, new NumberNode(0.0));
|
|
}
|
|
;
|
|
|
|
vector3: LESS expression COMMA expression COMMA expression GREATER {
|
|
$$ = new VectorNode($2, $4, $6);
|
|
}
|
|
;
|
|
|
|
expression: term { $$ = $1; }
|
|
| expression TIMES term { $$ = new BinOpNode('*', $1, $3); }
|
|
| expression DIVIDE term { $$ = new BinOpNode('/', $1, $3); }
|
|
| MINUS expression %prec UMINUS {
|
|
$$ = new BinOpNode('-', new NumberNode(0.0), $2);
|
|
}
|
|
| stmt_expression { $$ = $1; }
|
|
;
|
|
|
|
maybe_expression: /* empty */
|
|
| expression { $$ = $1; }
|
|
;
|
|
|
|
stmt_expression: assignment { $$ = $1; }
|
|
| local_assignment { $$ = $1; }
|
|
| local_decl { $$ = $1; }
|
|
;
|
|
|
|
bool_expression: expression LESS expression {
|
|
$$ = new BoolExpressionNode('<', $1, $3);
|
|
}
|
|
| expression GREATER expression {
|
|
$$ = new BoolExpressionNode('>', $1, $3);
|
|
}
|
|
| expression EQUALS expression {
|
|
$$ = new BoolExpressionNode('=', $1, $3);
|
|
}
|
|
| expression NOTEQUALS expression {
|
|
$$ = new BoolExpressionNode('n', $1, $3);
|
|
}
|
|
| NOT bool_expression {
|
|
$$ = new BoolExpressionNode('!', $2, NULL);
|
|
}
|
|
;
|
|
|
|
term: factor { $$ = $1; }
|
|
| term PLUS factor { $$ = new BinOpNode('+', $1, $3); }
|
|
| term MINUS factor { $$ = new BinOpNode('-', $1, $3); }
|
|
;
|
|
|
|
factor: number { $$ = $1; }
|
|
| VARREF { $$ = $1; }
|
|
| LPAREN expression RPAREN { $$ = $2; }
|
|
;
|
|
|
|
assignment: VARREF ASSIGN expression {
|
|
$$ = new AssignmentNode($1, $3);
|
|
}
|
|
;
|
|
|
|
local_assignment: LOCAL VARREF ASSIGN expression {
|
|
$$ = new LocalAssignmentNode($2, $4);
|
|
}
|
|
;
|
|
|
|
local_decl: LOCAL VARREF {
|
|
$$ = new LocalDeclNode($2);
|
|
}
|
|
;
|
|
|
|
for: FOR LPAREN maybe_expression SEMICOLON bool_expression SEMICOLON maybe_expression RPAREN LCURLY general_items RCURLY {
|
|
$$ = new ForNode($3, $5, $7);
|
|
$$->addChildren($10);
|
|
}
|
|
;
|
|
|
|
%%
|
|
|
|
refptr<Node> parse(const char * fileName, refptr<Scope> scope)
|
|
{
|
|
parser_scope = scope;
|
|
|
|
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);
|
|
}
|