User Guide
rename_visitor.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 Blue Brain Project, EPFL.
3  * See the top-level LICENSE file for details.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
9 
10 #include "ast/all.hpp"
11 #include "parser/c11_driver.hpp"
12 #include "utils/logger.hpp"
14 
15 
16 namespace nmodl {
17 namespace visitor {
18 
19 
20 std::string RenameVisitor::new_name_generator(const std::string& old_name) {
21  std::string new_name;
22  if (add_random_suffix) {
23  if (renamed_variables.find(old_name) != renamed_variables.end()) {
24  new_name = renamed_variables[old_name];
25  } else {
26  const auto& vars = get_global_vars(*ast);
27  if (add_prefix) {
28  new_name = suffix_random_string(vars,
29  new_var_name_prefix + old_name,
31  } else {
32  new_name =
34  }
35  renamed_variables[old_name] = new_name;
36  }
37  } else {
38  if (add_prefix) {
39  new_name = new_var_name_prefix + old_name;
40  } else {
41  new_name = new_var_name;
42  }
43  }
44  return new_name;
45 }
46 
47 /// rename matching variable
49  const auto& name = node.get_node_name();
50  if (std::regex_match(name, var_name_regex)) {
51  std::string new_name = new_name_generator(name);
52  node.get_value()->set(new_name);
53  std::string token_string = node.get_token() != nullptr
54  ? " at " + node.get_token()->position()
55  : "";
56  logger->debug("RenameVisitor :: Renaming variable {}{} to {}",
57  name,
58  token_string,
59  new_name);
60  }
61 }
62 
63 /** Prime name has member order which is an integer. In theory
64  * integer could be "macro name" and hence could end-up renaming
65  * macro. In practice this won't be an issue as we order is set
66  * by parser. To be safe we are only renaming prime variable.
67  */
69  node.visit_children(*this);
70 }
71 
72 /**
73  * Parse verbatim blocks and rename variable if it is used.
74  */
76  if (!rename_verbatim) {
77  return;
78  }
79 
80  const auto& statement = node.get_statement();
81  const auto& text = statement->eval();
83 
84  driver.scan_string(text);
85  auto tokens = driver.all_tokens();
86 
87  std::ostringstream result;
88  for (auto& token: tokens) {
89  if (std::regex_match(token, var_name_regex)) {
90  /// Check if variable is already renamed and use the same naming otherwise add the
91  /// new_name to the renamed_variables map
92  const std::string& new_name = new_name_generator(token);
93  result << new_name;
94  logger->debug("RenameVisitor :: Renaming variable {} in VERBATIM block to {}",
95  token,
96  new_name);
97  } else {
98  result << token;
99  }
100  }
101  statement->set(result.str());
102 }
103 
104 } // namespace visitor
105 } // namespace nmodl
nmodl::visitor::RenameVisitor::add_prefix
bool add_prefix
add prefix to variable name
Definition: rename_visitor.hpp:62
nmodl::ast::Verbatim
Represents a C code block.
Definition: verbatim.hpp:38
nmodl::ast::Name::get_value
std::shared_ptr< String > get_value() const noexcept
Getter for member variable Name::value.
Definition: name.hpp:162
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::visitor::RenameVisitor::visit_name
void visit_name(const ast::Name &node) override
rename matching variable
Definition: rename_visitor.cpp:48
nmodl::visitor::RenameVisitor::visit_prime_name
void visit_prime_name(const ast::PrimeName &node) override
Prime name has member order which is an integer.
Definition: rename_visitor.cpp:68
nmodl::logger
logger_type logger
Definition: logger.cpp:34
nmodl::ast::Verbatim::get_statement
std::shared_ptr< String > get_statement() const noexcept
Getter for member variable Verbatim::statement.
Definition: verbatim.hpp:157
nmodl::parser::CDriver
Class that binds all pieces together for parsing C verbatim blocks.
Definition: c11_driver.hpp:37
nmodl::ast::Name::get_token
const ModToken * get_token() const noexcept override
Return associated token for the current ast node.
Definition: name.hpp:141
nmodl::ModToken::position
std::string position() const
Return position of the token as string.
Definition: modtoken.cpp:14
nmodl::ast::PrimeName::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:887
visitor_utils.hpp
Utility functions for visitors implementation.
driver
nmodl::parser::UnitDriver driver
Definition: parser.cpp:28
nmodl::visitor::RenameVisitor::rename_verbatim
bool rename_verbatim
rename verbatim blocks as well
Definition: rename_visitor.hpp:68
c11_driver.hpp
nmodl::visitor::RenameVisitor::new_var_name
std::string new_var_name
new name
Definition: rename_visitor.hpp:52
nmodl::visitor::RenameVisitor::add_random_suffix
bool add_random_suffix
add random suffix
Definition: rename_visitor.hpp:65
nmodl::visitor::RenameVisitor::renamed_variables
std::unordered_map< std::string, std::string > renamed_variables
Map that keeps the renamed variables to keep the same random suffix when a variable is renamed across...
Definition: rename_visitor.hpp:59
nmodl::ast::PrimeName
Represents a prime variable (for ODE)
Definition: prime_name.hpp:48
nmodl::visitor::RenameVisitor::new_var_name_prefix
std::string new_var_name_prefix
variable prefix
Definition: rename_visitor.hpp:55
nmodl::ast::Name::get_node_name
std::string get_node_name() const override
Return name of the node.
Definition: ast.cpp:791
logger.hpp
Implement logger based on spdlog library.
nmodl::utils::WithoutNumbers
@ WithoutNumbers
Definition: common_utils.hpp:51
nmodl::ast::Name
Represents a name.
Definition: name.hpp:44
nmodl::visitor::RenameVisitor::new_name_generator
std::string new_name_generator(const std::string &old_name)
Check if variable is already renamed and use the same naming otherwise add the new_name to the rename...
Definition: rename_visitor.cpp:20
rename_visitor.hpp
Blindly rename given variable to new name
nmodl::visitor::suffix_random_string
std::string suffix_random_string(const std::set< std::string > &vars, const std::string &original_string, const UseNumbersInString use_num)
Return the "original_string" with a random suffix if "original_string" exists in "vars".
Definition: visitor_utils.cpp:32
nmodl::visitor::RenameVisitor::var_name_regex
std::regex var_name_regex
regex for searching which variables to replace
Definition: rename_visitor.hpp:49
nmodl::visitor::RenameVisitor::visit_verbatim
void visit_verbatim(const ast::Verbatim &node) override
Parse verbatim blocks and rename variable if it is used.
Definition: rename_visitor.cpp:75
nmodl::visitor::get_global_vars
std::set< std::string > get_global_vars(const Program &node)
Return set of strings with the names of all global variables.
Definition: visitor_utils.cpp:170
all.hpp
Auto generated AST classes declaration.
nmodl::visitor::RenameVisitor::ast
std::shared_ptr< ast::Program > ast
ast::Ast* node
Definition: rename_visitor.hpp:46