class ASTNode;
typedef std::map<std::string, std::string> PropertyContainer;
typedef std::vector<ASTNode> ChildContainer;
class ASTNode: PropertyContainer, ChildContainer
{
public:
ASTNode(){}
ASTNode(std::initializer_list<PropertyContainer::value_type> list)
: PropertyContainer (list)
{
}
ChildContainer::reference operator[](size_t index) _GLIBCXX_NOEXCEPT
{
return std::vector<ASTNode>::operator[](index);
}
ASTNode &operator << (const ASTNode &node) _GLIBCXX_NOEXCEPT
{
push_back(node); return *this;
}
size_t size() const _GLIBCXX_NOEXCEPT
{
return std::vector<ASTNode>::size();
}
template <typename Funct_>
void recursionChilds(Funct_ f) const _GLIBCXX_NOEXCEPT {
foreachChilds([=](ChildContainer::const_reference ref) {
ref.recursionChilds(f);
});
}
template <typename Funct_>
void recursion(Funct_ f) const _GLIBCXX_NOEXCEPT {
f(*this);
recursionChilds(f);
}
template <typename Funct_>
void recursion(Funct_ f, int &level) const _GLIBCXX_NOEXCEPT {
f(*this);
level ++;
foreachChilds([&](ChildContainer::const_reference ref) {
ref.recursion(f, level);
});
level --;
}
template <typename Funct_>
void foreachChilds(Funct_ f) const _GLIBCXX_NOEXCEPT {
std::for_each(ChildContainer::begin(), ChildContainer::end(), f);
}
template <typename Funct_>
void foreachPropertys(Funct_ f) const _GLIBCXX_NOEXCEPT {
std::for_each(PropertyContainer::begin(), PropertyContainer::end(), f);
}
PropertyContainer::mapped_type &operator[](const std::string &key) _GLIBCXX_NOEXCEPT
{
return PropertyContainer::operator[](key);
}
std::vector<PropertyContainer::key_type> keys() const _GLIBCXX_NOEXCEPT {
std::vector<PropertyContainer::key_type> ret;
auto itera = PropertyContainer::begin();
while (itera != PropertyContainer::end()) {
ret.push_back(itera->first);
itera ++;
}
return ret;
}
std::vector<PropertyContainer::mapped_type> values() const _GLIBCXX_NOEXCEPT {
std::vector<PropertyContainer::mapped_type> ret;
auto itera = PropertyContainer::begin();
while (itera != PropertyContainer::end()) {
ret.push_back(itera->second);
itera ++;
}
return ret;
}
size_t count() const _GLIBCXX_NOEXCEPT
{
return PropertyContainer::size();
}
void dump()
{
int level = 0;
recursion([&](ChildContainer::const_reference ref){
auto getHead = [=](int level) -> std::string {
int c = 0; std::string ret;
while (c < level) {
ret += " ";
c++;
}
return ret;
};
std::cout << getHead(level);
ref.foreachPropertys([&](PropertyContainer::const_reference ref)
{
std::cout << ref.first << ":" << ref.second << " ";
});
std::cout << std::endl;
}, level);
}
void dumpSave(const std::string &file)
{
std::ofstream ofstream;
ofstream.open(file);
int level = 0;
recursion([&](ChildContainer::const_reference ref){
auto getHead = [=](int level) -> std::string {
int c = 0; std::string ret;
while (c < level) {
ret += " ";
c++;
}
return ret;
};
ofstream << getHead(level);
ref.foreachPropertys([&](PropertyContainer::const_reference ref)
{
ofstream << ref.first << ":" << ref.second << " ";
});
ofstream << std::endl;
}, level);
}
void dumpLoad(const std::string &file)
{
}
};
ASTNode genRoot() {
ASTNode root{{"name", "root"}};
ASTNode one{{"name", "public"},{"start", "[0:0]"}};
ASTNode two{{"name", "class"},{"start", "[0:7]"}};
ASTNode three{{"name", "Hello"},{"start", "[0:13]"}};
root << one << two << three;
root[0] << one << two << three;
root[0][0] << one << two << three;
root[0][0][0] << one << two << three;
root[1] << one << two << three;
root[2] << one << two << three;
return root;
}
int main(int argc, char *argv[])
{
ASTNode root = genRoot();
root.dump();
}
C++实现通用AST语法树结构
于 2022-12-23 18:23:26 首次发布