14 namespace netlist_parser_manager
18 std::unordered_map<std::string, std::vector<std::string>> m_parser_to_extensions;
19 std::unordered_map<std::string, std::pair<std::string, ParserFactory>> m_extension_to_parser;
21 ParserFactory get_parser_factory_for_file(
const std::filesystem::path& file_name)
23 std::string extension =
utils::to_lower(file_name.extension().string());
24 if (!extension.empty() && extension[0] !=
'.')
26 extension =
"." + extension;
29 if (
auto it = m_extension_to_parser.find(extension); it != m_extension_to_parser.end())
31 log_info(
"netlist_parser",
"selected parser: {}", it->second.first);
32 return it->second.second;
35 log_error(
"netlist_parser",
"no netlist parser registered for file type '{}'", extension);
39 std::vector<std::unique_ptr<Netlist>>
40 dispatch_parse(
const std::filesystem::path& file_name, std::unique_ptr<NetlistParser>
parser,
const GateLibrary* gate_library =
nullptr,
bool break_on_match =
true)
42 auto begin_time = std::chrono::high_resolution_clock::now();
44 log_info(
"netlist_parser",
"parsing '{}'...", file_name.string());
46 if (
auto res =
parser->parse(file_name); res.is_error())
48 log_error(
"netlist_parser",
"failed to parse '{}':\n{}", file_name.string(), res.get_error().get());
53 "finished parsing in {:2.2f} seconds.",
54 (
double)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - begin_time).count() / 1000);
56 std::vector<std::unique_ptr<Netlist>>
netlists;
58 if (gate_library !=
nullptr)
60 begin_time = std::chrono::high_resolution_clock::now();
62 log_info(
"netlist_parser",
"instantiating '{}' with gate library '{}'...", file_name.string(), gate_library->get_name());
64 if (
auto res =
parser->instantiate(gate_library); res.is_error())
66 log_info(
"netlist_parser",
"failed to instantiate '{}' with gate library '{}':\n{}", file_name.string(), gate_library->get_name(), res.get_error().get());
72 netlist->set_input_filename(file_name.string());
75 "instantiated '{}' in {:2.2f} seconds.",
77 (
double)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - begin_time).count() / 1000);
84 log_warning(
"netlist_parser",
"no (valid) gate library specified, trying to auto-detect gate library...");
89 begin_time = std::chrono::high_resolution_clock::now();
91 log_info(
"netlist_parser",
"instantiating '{}' with gate library '{}'...", file_name.string(), lib_it->get_name());
93 if (
auto res =
parser->instantiate(lib_it); res.is_error())
95 log_info(
"netlist_parser",
"failed to instantiate '{}' with gate library '{}':\n{}", file_name.string(), lib_it->get_name(), res.get_error().get());
103 netlist->set_input_filename(file_name.string());
106 "instantiated '{}' in {:2.2f} seconds.",
108 (
double)std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - begin_time).count() / 1000);
121 log_error(
"netlist_parser",
"could not find suitable gate library.");
137 std::string extension =
utils::to_lower(file_name.extension().string());
138 if (!extension.empty() && extension[0] !=
'.')
140 extension =
"." + extension;
143 if (extension ==
".hal")
return true;
145 return (m_extension_to_parser.find(extension) != m_extension_to_parser.end());
150 for (
auto ext : supported_file_extensions)
153 if (!ext.empty() && ext[0] !=
'.')
157 if (
auto it = m_extension_to_parser.find(ext); it != m_extension_to_parser.end())
159 log_warning(
"netlist_parser",
"file type '{}' already has associated parser '{}', it remains unchanged", ext, it->second.first);
162 m_extension_to_parser.emplace(ext, std::make_pair(
name, parser_factory));
163 m_parser_to_extensions[
name].push_back(ext);
165 log_info(
"netlist_parser",
"registered netlist parser '{}' for file type '{}'",
name, ext);
171 if (
auto it = m_parser_to_extensions.find(
name); it != m_parser_to_extensions.end())
173 for (
const auto& ext : it->second)
175 if (
auto rm_it = m_extension_to_parser.find(ext); rm_it != m_extension_to_parser.end())
177 m_extension_to_parser.erase(rm_it);
178 log_info(
"netlist_parser",
"unregistered netlist parser '{}' which was registered for file type '{}'",
name, ext);
181 m_parser_to_extensions.erase(it);
187 ParserFactory factory = get_parser_factory_for_file(file_name);
195 if (
args.is_option_set(
"--gate-library"))
197 std::string gate_library_file =
args.get_parameter(
"--gate-library");
199 if (gate_library ==
nullptr)
201 log_error(
"netlist_parser",
"invalid gate library '{}' specified by user.", gate_library_file);
206 return parse(file_name, gate_library);
209 std::unique_ptr<Netlist>
parse(
const std::filesystem::path& file_name,
const GateLibrary* gate_library)
211 ParserFactory factory = get_parser_factory_for_file(file_name);
217 std::vector<std::unique_ptr<Netlist>>
netlists = dispatch_parse(file_name, factory(), gate_library);
227 std::vector<std::unique_ptr<Netlist>>
parse_all(
const std::filesystem::path& file_name)
229 ParserFactory factory = get_parser_factory_for_file(file_name);
235 return dispatch_parse(file_name, factory(),
nullptr,
false);
240 return m_parser_to_extensions;
#define log_error(channel,...)
#define log_info(channel,...)
#define log_warning(channel,...)
std::vector< GateLibrary * > get_gate_libraries()
void load_all(bool reload)
GateLibrary * get_gate_library(const std::string &file_path)
void unregister_parser(const std::string &name)
std::unordered_map< std::string, std::vector< std::string > > get_parser_to_extensions()
std::function< std::unique_ptr< NetlistParser >()> ParserFactory
ProgramOptions get_cli_options()
bool can_parse(const std::filesystem::path &file_name)
void register_parser(const std::string &name, const ParserFactory &parser_factory, const std::vector< std::string > &supported_file_extensions)
std::unique_ptr< Netlist > parse(const std::filesystem::path &file_name, const ProgramArguments &args)
std::vector< std::unique_ptr< Netlist > > parse_all(const std::filesystem::path &file_name)
CORE_API T trim(const T &s, const char *to_remove=" \t\r\n")
CORE_API T to_lower(const T &s)