help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Token types with constructor


From: Hans Aberg
Subject: Re: Token types with constructor
Date: Tue, 14 Sep 2004 00:56:52 +0200

At 10:50 +0200 2004/09/13, Akim Demaille wrote:
> > I cannot use the Bison %union then, because of the limitation of C++ to not
> > use non-POD's in unions, but I experimented with a %type feature which does
> > not implement unions. But in this polymorphic approach I use, it turns out
> > not to be every essential, as an erroneous type operation will cause a C++
> > runtime dynamic_cast exception. But others ay want a %type feature for
> > keeping track of a static pointer.
>
>We cannot afford such a solution in Bison, for performance reasons.
>First, the copy are expensive because of the size of the stack
>members, plus the ctor they involve, and in addition dynamic_cast is
>an expensive operation.

One can use static_cast instead, if one knows the static type. The C++
standard ISO+IEC+14882-1998 says in [expr.static.cast] 5.2.9 Static cast:

An rvalue of type "pointer to cv1 B", where B is a class type, can be
converted to an rvalue of type "pointer to cv2 D", where D is a class
derived (clause 10) from B, if a valid standard conversion from "pointer to
D"
to "pointer to B" exists (4.10), cv2 is the same cv-qualification as, or
greater cv-qualification than, cv1, and B is not a virtual base class of D.
The null pointer value (4.10) is converted to the null pointer value of the
destination type. If the rvalue of type "pointer to cv1 B" points to a B
that is actually a sub-object of an object of type D, the resulting pointer
points to the enclosing object of type D. Otherwise, the result of the cast
is undefined.

This might then be used with a Bison %typed option, as to make the
conversions transparent.

The idea would something like this: One creates a template class ref<T>
holding a pointer to T*, which is assumed to be reference counted. One then
derives all classes T in the hierarchy from object_root. Then set class
object = ref<object_root>.

When one, in the parser, creates a pointer new T(...), one converts to a
class object object. If one, in a rule needs to apply $k.object_, and the
static type is known, say T, one applies static_cast<T*>($k.object_.data_)
to get the T* value, which the can further be converted to a ref<T> (the
ref counter needs to be increased).

I have in reality a hierarchy of such T's where I have written some ref<T>
classes. I have specially designed these classes so that the null pointer
sometimes have special meaning. For example, in the class substitution, the
null pointer represents the identity substitution. If one does that, it is
hard to use a single template class ref<T> to define those reference
classes.

Then dynamic_cast is only needed in special circumstances. For example, if
I build closures by rules
    formula:
        formula "|" formula {...}
      | formula "," formula {...}
      ...
   ;
then the variable "formula" will have a specific static typing in my
program, namely a "formula". But if I want to find out which is the top
level operator of the closure being built, then I have to write code
something like:
    op_meta_and* op = dynamic_cast<op_meta_and*>($k.object_.data_);
    if (op != 0)
      // Do the code when top level is ",".
    ...
But this cannot be avoided.

This way, one gets the advantage of C++ taking care of the cleanup during
stack unwinding.

  Hans Aberg






reply via email to

[Prev in Thread] Current Thread [Next in Thread]