mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
glr2.cc: make the example more C++
Currently the example really looks like C. Instead of a union of structs to implement the AST, use a hierarchy. It would be nice to feature a C++17 version with std variants. * examples/c++/glr/c++-types.yy (Node, free_node, new_nterm) (new_term): Move into... * examples/c++/glr/ast.hh: here, a proper C++ hierarchy.
This commit is contained in:
100
examples/c++/glr/ast.hh
Normal file
100
examples/c++/glr/ast.hh
Normal file
@@ -0,0 +1,100 @@
|
||||
#include <iostream>
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
# define nullptr 0
|
||||
#endif
|
||||
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
Node ()
|
||||
: parents_ (0)
|
||||
{}
|
||||
|
||||
virtual ~Node ()
|
||||
{}
|
||||
|
||||
void free ()
|
||||
{
|
||||
parents_ -= 1;
|
||||
/* Free only if 0 (last parent) or -1 (no parents). */
|
||||
if (parents_ <= 0)
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual std::ostream& print (std::ostream& o) const = 0;
|
||||
|
||||
protected:
|
||||
friend class Nterm;
|
||||
friend class Term;
|
||||
int parents_;
|
||||
};
|
||||
|
||||
|
||||
static std::ostream&
|
||||
operator<< (std::ostream& o, const Node &node)
|
||||
{
|
||||
return node.print (o);
|
||||
}
|
||||
|
||||
class Nterm : public Node
|
||||
{
|
||||
public:
|
||||
Nterm (char const *form,
|
||||
Node *child0 = nullptr, Node *child1 = nullptr, Node *child2 = nullptr)
|
||||
: form_ (form)
|
||||
{
|
||||
children_[0] = child0;
|
||||
if (child0)
|
||||
child0->parents_ += 1;
|
||||
children_[1] = child1;
|
||||
if (child1)
|
||||
child1->parents_ += 1;
|
||||
children_[2] = child2;
|
||||
if (child2)
|
||||
child2->parents_ += 1;
|
||||
}
|
||||
|
||||
~Nterm ()
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
if (children_[i])
|
||||
children_[i]->free ();
|
||||
}
|
||||
|
||||
std::ostream& print (std::ostream& o) const
|
||||
{
|
||||
o << form_;
|
||||
if (children_[0])
|
||||
{
|
||||
o << '(' << *children_[0];
|
||||
if (children_[1])
|
||||
o << ", " << *children_[1];
|
||||
if (children_[2])
|
||||
o << ", " << *children_[2];
|
||||
o << ')';
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
private:
|
||||
char const *form_;
|
||||
Node *children_[3];
|
||||
};
|
||||
|
||||
class Term : public Node
|
||||
{
|
||||
public:
|
||||
Term (const std::string &text)
|
||||
: text_ (text)
|
||||
{}
|
||||
|
||||
std::ostream& print (std::ostream& o) const
|
||||
{
|
||||
o << text_;
|
||||
return o;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string text_;
|
||||
};
|
||||
Reference in New Issue
Block a user