help-bison
[Top][All Lists]
Advanced

[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






reply via email to

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