1 #include <core/assert.hh>
4 #include <boost/foreach.hpp>
6 #include "generator.hh"
8 namespace ag
= ast::generator
;
11 generateAsciiVisitorHeader(const char * working_directory
)
13 assert(working_directory
);
16 std::string
path(working_directory
);
18 path
.append("/ascii-visitor.hh");
19 out
.open(path
.c_str(), std::fstream::out
| std::fstream::trunc
);
20 assert(out
.is_open() && out
.good());
24 ag::appendGeneratedWarning(out
);
25 out
<< "#ifndef AST_ASCII_VISITOR_HH" NL
26 << "# define AST_ASCII_VISITOR_HH" NL NL
27 << "#include <ast/browse-visitor.hh>" NL NL
31 out
<< " /** @defgroup Visitors */" NL
33 << " * @brief A visitor which dump the AST on the standard output." NL
34 << " * @ingroup Visitors" NL
36 << " class AsciiVisitor : public ConstBrowseVisitor" NL
39 << " AsciiVisitor();" NL
40 << " virtual ~AsciiVisitor();" NL NL
;
42 for (node
= ag::nodes
; !node
->name
.empty() > 0; node
++)
43 out
<< " virtual void visit(const " << node
->name
<< " & node);" NL
;
45 out
<< " protected:" NL
46 << " int depth_; ///< The depht in the ast." NL
47 << " std::string name_; ///< The name of the node." NL
48 << " std::string prefix_; ///< The name of the node." NL
51 out
<< "} // namespace ast" NL
52 << "#endif // !AST_ASCII_VISITOR_HH" NL
;
57 #define ctype "\e[34m"
58 #define cchev "\e[33m"
59 #define cbrack "\e[35m"
62 generateAsciiVisitorSource(const char * working_directory
)
64 assert(working_directory
);
67 std::string
path(working_directory
);
69 path
.append("/ascii-visitor.cc");
70 out
.open(path
.c_str(), std::fstream::out
| std::fstream::trunc
);
71 assert(out
.is_open() && out
.good());
75 ag::appendGeneratedWarning(out
);
76 out
<< "#include <iostream>" NL
77 << "#include <sstream>" NL
78 << "#include <boost/foreach.hpp>" NL
79 << "#include <ast/ascii-visitor.hh>" NL NL
80 << "#define NL << std::endl" NL NL
84 out
<< " AsciiVisitor::AsciiVisitor()" NL
85 << " : depth_(-1), name_(), prefix_()"
87 << " AsciiVisitor::~AsciiVisitor() {}" NL NL
;
89 for (node
= ag::nodes
; !node
->name
.empty() > 0; node
++)
91 out
<< " void AsciiVisitor::visit(const " << node
->name
<< " & node)" NL
94 << " std::string oldName = name_;" NL
95 << " std::string oldPrefix = prefix_;" NL NL
97 << " std::cout << prefix_ << \"`- \";" NL
98 << " if (!name_.empty())" NL
99 << " std::cout << name_ << \" \";" NL
100 << " std::cout << \""cchev
"<"ctype
<< node
->name
<< cchev
">\e[m\" NL;" NL
;
103 std::vector
<const ag::Attribute
*> allAttrs
= ag::allAttributes(node
);
104 BOOST_FOREACH(const ag::Attribute
* attr
, allAttrs
)
107 out
<< " name_ = \"" << attr
->name
<< "\";" NL
;
108 if (ag::isNode(attr
->type
))
109 out
<< " if (node." << attr
->name
<< ")" NL
111 << " prefix_ = oldPrefix;" NL
112 << " prefix_.append(\" "
113 << (i
< allAttrs
.size() ? "|" : " ") << "\");" NL
114 << " node." << attr
->name
<< "->accept(*this);" NL
116 else if (ag::isVectorOfNode(attr
->type
))
119 << " if (node." << attr
->name
<< ")" NL
120 << " BOOST_FOREACH(Node * n, (*node." << attr
->name
<< "))" NL
122 << " std::stringstream ss;" NL
123 << " ss << \""cbrack
"["cclear
"\" << i << \""cbrack
"]"cclear
"\";" NL
124 << " name_ = \"" << attr
->name
<< "\";" NL
125 << " name_.append(ss.str());" NL
126 << " prefix_ = oldPrefix;" NL
;
128 if (i
< allAttrs
.size())
129 out
<< " prefix_.append(\" |\");" NL
;
131 out
<< " if (i == node." << attr
->name
<< "->size() - 1)"
132 << " prefix_.append(\" \");" NL
134 << " prefix_.append(\" |\");" NL
;
135 out
<< " n->accept(*this);" NL
139 else if (ag::isPrintable(attr
->type
))
140 out
<< " std::cout << oldPrefix << \" "
141 << (i
< allAttrs
.size() ? "|" : " ") << "\";" NL
142 << " std::cout << \"`- " << attr
->name
<< cchev
" <" ctype
<< attr
->type
143 << cchev
">\e[m = \" << node." << attr
->name
<< " NL;" NL
;
145 out
<< " --depth_;" NL
146 << " name_ = oldName;" NL
;
151 out
<< "} // namespace ast" NL
;
155 int main(int argc
, char **argv
)
158 generateAsciiVisitorHeader(argv
[1]);
159 generateAsciiVisitorSource(argv
[1]);