#include <language/PugsParser.hpp> #include <language/PEGGrammar.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTModulesImporter.hpp> #include <language/ast/ASTNode.hpp> #include <language/ast/ASTNodeDataTypeBuilder.hpp> #include <language/ast/ASTNodeDataTypeChecker.hpp> #include <language/ast/ASTNodeDeclarationToAffectationConverter.hpp> #include <language/ast/ASTNodeEmptyBlockCleaner.hpp> #include <language/ast/ASTNodeExpressionBuilder.hpp> #include <language/ast/ASTNodeJumpPlacementChecker.hpp> #include <language/ast/ASTNodeTypeCleaner.hpp> #include <language/ast/ASTSymbolInitializationChecker.hpp> #include <language/ast/ASTSymbolTableBuilder.hpp> #include <language/utils/ASTDotPrinter.hpp> #include <language/utils/ASTPrinter.hpp> #include <language/utils/SymbolTable.hpp> #include <utils/PugsAssert.hpp> #include <utils/PugsUtils.hpp> #include <utils/SignalManager.hpp> #include <pegtl/contrib/analyze.hpp> #include <pegtl/contrib/parse_tree.hpp> #include <pegtl/contrib/parse_tree_to_dot.hpp> #include <rang.hpp> #include <fstream> #include <iostream> #include <sstream> #include <unordered_map> #include <variant> void parser(const std::string& filename) { const size_t grammar_issues = analyze<language::grammar>(); std::cout << rang::fgB::yellow << "grammar_issues=" << rang::fg::reset << grammar_issues << '\n'; std::cout << rang::style::bold << "Parsing file " << rang::style::reset << rang::style::underline << filename << rang::style::reset << " ...\n"; auto parse_and_execute = [](auto& input) { std::unique_ptr<ASTNode> root_node = ASTBuilder::build(input); ASTModulesImporter{*root_node}; ASTNodeTypeCleaner<language::import_instruction>{*root_node}; ASTSymbolTableBuilder{*root_node}; ASTSymbolInitializationChecker{*root_node}; ASTNodeDataTypeBuilder{*root_node}; ASTNodeDataTypeChecker{*root_node}; ASTNodeJumpPlacementChecker{*root_node}; // optimizations ASTNodeDeclarationToAffectationConverter{*root_node}; ASTNodeTypeCleaner<language::var_declaration>{*root_node}; ASTNodeTypeCleaner<language::fct_declaration>{*root_node}; { std::string dot_filename{"parse_tree.dot"}; std::ofstream fout(dot_filename); ASTDotPrinter dot_printer{*root_node}; fout << dot_printer; std::cout << " AST dot file: " << dot_filename << '\n'; } ASTNodeEmptyBlockCleaner{*root_node}; ASTNodeExpressionBuilder{*root_node}; std::cout << ASTPrinter{*root_node} << '\n'; auto& function_table = root_node->m_symbol_table->functionTable(); for (size_t i_function = 0; i_function < function_table.size(); ++i_function) { const auto& function_descriptor = function_table[i_function]; std::cout << "function " << rang::fgB::magenta << function_descriptor.name() << rang::style::reset << '\n'; std::cout << ASTPrinter(function_descriptor.domainMappingNode()); std::cout << ASTPrinter(function_descriptor.definitionNode()); std::cout << "--------\n"; } ExecutionPolicy exec_all; root_node->execute(exec_all); std::cout << *(root_node->m_symbol_table) << '\n'; root_node->m_symbol_table->clearValues(); }; if (not SignalManager::pauseOnError()) { read_input input(filename); try { parse_and_execute(input); } catch (const ParseError& e) { const auto p = e.positions().front(); std::cerr << rang::style::bold << p.source << ':' << p.line << ':' << p.column << ": " << rang::style::reset << rang::fgB::red << "error: " << rang::fg::reset << rang::style::bold << e.what() << rang::style::reset << '\n' << input.line_at(p) << '\n' << std::string(p.column, ' ') << rang::fgB::yellow << '^' << rang::fg::reset << '\n'; finalize(); std::exit(1); } } else { read_input input(filename); parse_and_execute(input); } std::cout << "Executed successfuly: " << filename << '\n'; }