diff --git a/src/language/ASTDotPrinter.cpp b/src/language/ASTDotPrinter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..270438e16b90d4cfd4c31ac35955878e9bcb81b1 --- /dev/null +++ b/src/language/ASTDotPrinter.cpp @@ -0,0 +1,43 @@ +#include <ASTDotPrinter.hpp> +#include <EscapedString.hpp> + +#include <PEGGrammar.hpp> + +void +ASTDotPrinter::_print(std::ostream& os, const ASTNode& node) const +{ + if (node.is_root()) { + os << " x" << &node << " [ label=\"root \\n" << dataTypeName(node.m_data_type) << "\" ]\n"; + } else { + if (node.has_content()) { + os << " x" << &node << " [ label=\"" << node.name() << "\\n" + << node.string_view() << "\\n" + << dataTypeName(node.m_data_type) << "\" ]\n"; + } else { + os << " x" << &node << " [ label=\"" << node.name() << "\\n" << dataTypeName(node.m_data_type) << "\" ]\n"; + } + } + if (!node.children.empty()) { + os << " x" << &node << " -> { "; + for (auto& child : node.children) { + os << "x" << child.get() << ((child == node.children.back()) ? " }\n" : ", "); + } + for (auto& child : node.children) { + this->_print(os, *child); + } + } +} + +std::ostream& +operator<<(std::ostream& os, const ASTDotPrinter& ast_printer) +{ + os << "digraph parse_tree\n{\n"; + ast_printer._print(os, ast_printer.m_node); + os << "}\n"; + return os; +} + +ASTDotPrinter::ASTDotPrinter(const ASTNode& node) : m_node{node} +{ + Assert(node.is_root()); +} diff --git a/src/language/ASTDotPrinter.hpp b/src/language/ASTDotPrinter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..522f59b17a800664f21226da6f629c8aa83cebb3 --- /dev/null +++ b/src/language/ASTDotPrinter.hpp @@ -0,0 +1,25 @@ +#ifndef AST_DOT_PRINTER_HPP +#define AST_DOT_PRINTER_HPP + +#include <ASTNode.hpp> + +class ASTDotPrinter +{ + private: + const ASTNode& m_node; + + void _print(std::ostream& os, const ASTNode& node) const; + + public: + friend std::ostream& operator<<(std::ostream& os, const ASTDotPrinter& ast_printer); + + ASTDotPrinter(const ASTNode& node); + + ASTDotPrinter(const ASTDotPrinter&) = delete; + + ASTDotPrinter(ASTDotPrinter&&) = delete; + + ~ASTDotPrinter() = default; +}; + +#endif // AST_DOT_PRINTER_HPP diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index 6f9d049434b12ccbca3919d8dfcda247e853c23e..c99aa359270586271348d6e7b72a1392745baaf0 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) add_library( PugsLanguage ASTBuilder.cpp + ASTDotPrinter.cpp ASTNodeDataType.cpp ASTNodeAffectationExpressionBuilder.cpp ASTNodeBinaryOperatorExpressionBuilder.cpp diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index bdc4b87034e98e6cf1ebe5dca4621d4d7570812e..8f85044d192728a07edc34c2b8bded238ac38f2d 100644 --- a/src/language/PugsParser.cpp +++ b/src/language/PugsParser.cpp @@ -26,48 +26,11 @@ #include <ASTSymbolInitializationChecker.hpp> #include <ASTSymbolTableBuilder.hpp> +#include <ASTDotPrinter.hpp> #include <ASTPrinter.hpp> namespace language { -namespace internal -{ -void -print_dot(std::ostream& os, const ASTNode& n) -{ - if (n.is_root()) { - os << " x" << &n << " [ label=\"root \\n" << dataTypeName(n.m_data_type) << "\" ]\n"; - } else { - if (n.has_content()) { - os << " x" << &n << " [ label=\"" << n.name() << "\\n" - << n.string_view() << "\\n" - << dataTypeName(n.m_data_type) << "\" ]\n"; - } else { - os << " x" << &n << " [ label=\"" << n.name() << "\\n" << dataTypeName(n.m_data_type) << "\" ]\n"; - } - } - if (!n.children.empty()) { - os << " x" << &n << " -> { "; - for (auto& child : n.children) { - os << "x" << child.get() << ((child == n.children.back()) ? " }\n" : ", "); - } - for (auto& child : n.children) { - print_dot(os, *child); - } - } -} - -} // namespace internal - -void -print_dot(std::ostream& os, const ASTNode& n) -{ - Assert(n.is_root()); - os << "digraph parse_tree\n{\n"; - internal::print_dot(os, n); - os << "}\n"; -} - namespace internal { void @@ -364,7 +327,8 @@ parser(const std::string& filename) { std::string dot_filename{"parse_tree.dot"}; std::ofstream fout(dot_filename); - language::print_dot(fout, *root_node); + ASTDotPrinter dot_printer{*root_node}; + fout << dot_printer; std::cout << " AST dot file: " << dot_filename << '\n'; }