Skip to content
Snippets Groups Projects
Select Git revision
  • 720d122e62819e9b49e4f2d8d94239482160682d
  • develop default protected
  • feature/gmsh-reader
  • origin/stage/bouguettaia
  • feature/kinetic-schemes
  • feature/reconstruction
  • feature/local-dt-fsi
  • feature/composite-scheme-sources
  • feature/composite-scheme-other-fluxes
  • feature/serraille
  • feature/variational-hydro
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • master protected
  • feature/escobar-smoother
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
33 results

PugsParser.cpp

Blame
  • PugsParser.cpp 4.97 KiB
    #include <language/PugsParser.hpp>
    
    #include <language/PEGGrammar.hpp>
    #include <language/ast/ASTBuilder.hpp>
    #include <language/ast/ASTExecutionStack.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/ASTExecutionInfo.hpp>
    #include <language/utils/ASTPrinter.hpp>
    #include <language/utils/Exit.hpp>
    #include <language/utils/OperatorRepository.hpp>
    #include <language/utils/SymbolTable.hpp>
    #include <utils/ConsoleManager.hpp>
    #include <utils/ExecutionStatManager.hpp>
    #include <utils/Messenger.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 <memory>
    #include <sstream>
    #include <unordered_map>
    #include <variant>
    
    void
    parser(const std::string& filename)
    {
      const size_t grammar_issues = TAO_PEGTL_NAMESPACE::analyze<language::grammar>();
    
      if (grammar_issues != 0) {
        std::ostringstream os;
        os << "invalid grammar: " << rang::fgB::yellow << grammar_issues << rang::fg::reset << " were detected!";
        throw UnexpectedError(os.str());
      }
    
      if (ConsoleManager::showPreamble()) {
        std::cout << rang::style::bold << "Parsing file " << rang::style::reset << rang::style::underline << filename
                  << rang::style::reset << " ...\n";
      }
    
      auto parse_and_execute = [](auto& input, const std::string& file_content) {
        OperatorRepository::create();
    
        ASTExecutionStack::create(input, file_content);
        std::unique_ptr<ASTNode> root_node = ASTBuilder::build(*input);
    
        ASTModulesImporter module_importer{*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};
    
        ASTNodeEmptyBlockCleaner{*root_node};
    
        ASTNodeExpressionBuilder{*root_node};
    
        if (ConsoleManager::showPreamble()) {
          std::cout << "-------------------------------------------------------\n";
          std::cout << rang::style::bold << "Executing AST..." << rang::style::reset << '\n';
        }
    
        ASTExecutionInfo execution_info{*root_node, module_importer.moduleRepository()};
    
        ExecutionPolicy exec_all;
        try {
          root_node->execute(exec_all);
        }
        catch (language::Exit& e) {
          ExecutionStatManager::getInstance().setExitCode(e.code());
        }
        root_node->m_symbol_table->clearValues();
    
        OperatorRepository::destroy();
      };
    
      std::string file_content;
      if (parallel::rank() == 0) {
        std::ifstream file{filename};
        file_content = std::string{std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()};
      }
      parallel::broadcast(file_content, 0);
    
      auto input = std::make_shared<TAO_PEGTL_NAMESPACE::string_input<>>(file_content, filename);
    
      if (not SignalManager::pauseOnError()) {
        try {
          parse_and_execute(input, file_content);
        }
        catch (const ParseError& e) {
          const auto p = e.positions().front();
    
          std::string error_specifier = [] {
            std::ostringstream os;
            os << rang::style::bold << "error:" << rang::style::reset << ' ';
            return os.str();
          }();
    
          std::string message = e.what();
    
          // This is a cosmetic hack to avoid repetition of "error: " in
          // output
          if (message.substr(0, error_specifier.size()) == error_specifier) {
            message = message.substr(error_specifier.size());
          }
    
          std::cerr << rang::style::bold << p.source << ':' << p.line << ':' << p.column << ": " << rang::style::reset
                    << rang::fgB::red << "error: " << rang::fg::reset << rang::style::bold << message << rang::style::reset
                    << '\n'
                    << input->line_at(p) << '\n'
                    << std::string(p.column - 1, ' ') << rang::fgB::yellow << '^' << rang::fg::reset << '\n';
          finalize();
          std::exit(1);
        }
        catch (const IExitError& e) {
          std::cerr << ASTExecutionStack::getInstance().errorMessageAt(e.what()) << '\n';
    
          finalize();
          std::exit(1);
        }
      } else {
        parse_and_execute(input, file_content);
      }
    }