[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: bison %union and C++
From: |
Hans Aberg |
Subject: |
Re: bison %union and C++ |
Date: |
Tue, 24 Sep 2002 14:57:24 +0200 |
Reply-to: address@hidden
At 12:14 +1200 2002/09/24, Oleg Smolsky wrote:
>here is a question that is probably asked for a millionth time....
So you have figured it out. :-)
>Anyway, with bison 1.49b and C++ skeleton, how do I include a C++
>class into the bison's types? In theory, I would like to add
>std::string into the %union section, but this is prohibited by ANSI
>C++.
Just define your own class and YYSTYPE, and don't use unions in any form.
-- I suggested Bison having a %typed option augmenting %union that could be
used for Bison static checks of C++ polymorphic variables, but for some
reason they haven't implement anything like that.
>So, is there any way to get bison to store one of my objects on its
>stack?
For example:
class my_parser_type {
public:
long number;
std::string text;
my::object object_;
my_parser_type() : number(0) { }
};
#define YYSTYPE my_parser_type
Here I have used the strategy to carry along a few frequently used small
values like long & std::string, and putting the rest in a polymorphic
variable my::object:
namespace my {
class object;
class object_root {
mutable unsigned count_;
public:
object_root() : count_(1) {}
virtual ~object_root() {}
object_root* copy() const { ++count_; return
const_cast<object_root*>(this); }
void shed() { if (--count_ == 0) delete this; }
virtual object_root* clone() const = 0;
...
virtual void write(std::ostream& os) const = 0;
};
class object {
protected:
object_root* data_;
public:
object_root* copy() const { return (data_ == 0)? 0 : data_->copy(); }
void shed() { if (data_ != 0) data_->shed(); }
object() : data_(0) {}
~object() { shed(); }
object(const object& x) : data_(x.copy()) {}
object& operator=(const object& x) {
if (data_ != x.data_) { shed(); data_ = x.copy(); }
return *this;
}
object(object_root* rp) : data_(rp) {}
object_root* data() { return data_; }
const object_root* data() const { return data_; }
...
void write(std::ostream& os) const {
if (data_ == 0) os << "none";
else data_->write(os);
}
};
} // namespace my
Then add new polymorphic types by deriving from object_root:
class my_class : public virtual object_root {
...
public:
my_class()
virtual object_root* clone() const { return new my_class(*this); }
...
virtual void write(std::ostream& os) const {...}
};
Hans Aberg