|
![](/i/fill.gif) |
Ronald L. Parker <par### [at] mail fwi com> wrote in article
<36916860.164025814@news.povray.org>...
> On Mon, 04 Jan 1999 22:54:42 +0100, "Thorsten Froehlich"
> <fro### [at] charlie cns iit edu> wrote:
>
> >Yes, you are right that the parsing part does not build anything, but
please pay
> >attention to this little detail:
> >Look at the lines you did not mark, what do they do? They reduce the
memory usage!
> ...
> >All these lines of code would have to be written inside the grammar
file, wouldn't
> >they? And this would make the grammar file a total nightmare!!! Or how
would you
> >solve this problem, maybe I am totally wrong!?!
>
> You just call a function that contains the elided bits of code using
> the parameters you've parsed out. It still happens at parse time.
> I'm not too quick on the Bison grammar specification language myself,
> but I believe you would just pass the parsed vector into the
> "do_scale" function, defined somewhere else, and be on your way. Yes,
> you might have to store the vector somewhere temporarily, but you will
> only need to store one such vector for a scale command, and it can
> even be in a global variable.
PMJI, but having programmed on POV-Ray, as well as building a renderer
using LEX/YACC for the grammar, I believe that using Flex/Bison for parsing
POV-Ray would be quite a reasonable thing to do.
The assertion that the stack gets too deep as a result of object modifiers
like scale is pretty easily dealt with. Below is a sample of how I handled
object definition/modification in Polyray. [Note that ACTION() is a C
#define that checks to see if we are actually creating geometry, or if we
are just reading the file - it was a useful way to put "if () else ..."
type statements into the language.]
In general you only need a line or two of C/C++ for each rule. Typically
this code calls support routines.
Note that building from within an IDE is also quite easy - for example
Visual C++ allows quite flexible pre and post build steps, as well as the
typical ability to manage dependencies.
The big advantage of biting the bullet and using LEX/YACC is that it forces
you to develop a regular gammar. OTOH, a recursive descent parser (like
POV-Ray uses) is a really easy thing to write and manage. I'm not sure
there's a compelling reason for the POV-Ray team to change.
Sample LEX/YACC code for parsing an object & it's modifiers:
object
: OBJECT '{'
{ ACTION(Object_Stack = push_object(Object_Stack, object_action1());)
}
object_decls '}'
{ ACTION($<obj>$ = pop_object(&Object_Stack);) }
| OBJECT_SYM
{ ACTION($<obj>$ = object_action2($<name>1);) }
| OBJECT_SYM '{'
{ ACTION(Object_Stack =
push_object(Object_Stack, object_action2($<name>1));) }
object_modifier_decls '}'
{ ACTION($<obj>$ = pop_object(&Object_Stack);) }
;
object_modifier_decls
: object_modifier_decl
| object_modifier_decls object_modifier_decl
;
object_modifier_decl
: texture
{ ACTION(if (Object_Stack->element->o_texture != NULL)
TextureDelete(Object_Stack->element->o_texture);
Object_Stack->element->o_texture = $<text>1;) }
| transform
{ ACTION(TransformObject(Object_Stack->element, $<trns>1);
polyray_free($<trns>1);) }
| ROTATE point
{ ACTION(RotateObject(Object_Stack->element, $<vec>2);) }
| ROTATE point ',' fexper
{ ACTION(RotateAxisObject(Object_Stack->element, $<vec>2, $<flt>4);)
}
| SHEAR fexper ',' fexper ',' fexper ',' fexper ','
fexper ',' fexper
{ ACTION(ShearObject(Object_Stack->element, $<flt>2, $<flt>4,
$<flt>6, $<flt>8, $<flt>10, $<flt>12);) }
| TRANSLATE point
{ ACTION(TranslateObject(Object_Stack->element, $<vec>2);) }
| SCALE point
{ ACTION(ScaleObject(Object_Stack->element, $<vec>2);) }
| uv_information
| SHADING_FLAGS fexper
{ ACTION(Object_Stack->element->o_sflag = (int)$<flt>2;) }
| DITHER fexper
{ ACTION(Object_Stack->element->o_dither = $<flt>2;) }
| BOUNDING_BOX point ',' point
{ ACTION(VecCopy($<vec>2, Object_Stack->element->o_bnd.lower_left);
VecCopy($<vec>4, Object_Stack->element->o_bnd.lengths);
VecSub(Object_Stack->element->o_bnd.lengths,
Object_Stack->element->o_bnd.lower_left,
Object_Stack->element->o_bnd.lengths);) }
| root_solver
| DISPLACE expression
{ ACTION(Object_Stack->element->o_displace = $<exper>2;) }
;
Post a reply to this message
|
![](/i/fill.gif) |