16 namespace fs = std::filesystem;
22 : trace_scanner(strace)
23 , trace_parser(ptrace) {}
28 NmodlParser parser(scanner, *
this);
44 const location* loc) {
45 if (fs::is_directory(filename)) {
46 throw std::runtime_error(
"NMODL Parser Error : path " + filename.string() +
47 " appears to be a directory, please provide a file instead");
49 std::ifstream in(filename);
51 std::ostringstream oss;
53 oss <<
"NMODL Parser Error : ";
55 oss <<
"can not open file : " << filename;
59 throw std::runtime_error(oss.str());
65 auto absolute_path = fs::absolute(filename);
67 if (filename.is_absolute()) {
68 const auto path_prefix = filename.parent_path();
70 absolute_path = filename.string();
71 }
else if (!filename.has_parent_path()) {
74 const auto path_prefix = filename.parent_path();
75 const auto path = fs::absolute(path_prefix);
80 open_files.emplace(absolute_path.string(), loc);
90 std::istringstream iss(input);
96 const location& loc) {
105 auto absolute_path = name;
107 if (!directory_path.empty()) {
108 absolute_path = directory_path / name;
112 auto already_included =
open_files.find(absolute_path.string());
114 std::ostringstream oss;
115 oss << name <<
": recursive inclusion.\n";
116 if (already_included->second !=
nullptr) {
117 oss << *already_included->second <<
": initial inclusion was here.";
122 std::shared_ptr<ast::Program> program;
128 auto filename_node = std::shared_ptr<ast::String>(
129 new ast::String(fmt::format(
"\"{}\"", name.string())));
130 return std::shared_ptr<ast::Include>(
new ast::Include(filename_node, program->get_blocks()));
144 return var_it->second;
146 throw std::runtime_error(
"Trying to get undefined macro / define :" + name);
150 std::ostringstream oss;
151 oss <<
"NMODL Parser Error : " << message <<
" [Location : " << location <<
"]";
152 throw std::runtime_error(oss.str());
156 const location& location,
157 const std::string& message) {
158 std::ostringstream oss;
159 oss <<
"NMODL Parser Error : " << message <<
" [Location : " << location <<
"]";
161 oss << std::string(location.begin.column - 1,
'-');
165 throw std::runtime_error(oss.str());
169 const std::string& filename) {
170 if (filename.empty()) {
171 parse_error(location,
"empty filename in INCLUDE directive");
172 }
else if (filename.front() !=
'"' && filename.back() !=
'"') {
173 parse_error(location,
"filename may start and end with \" character");
174 }
else if (filename.size() == 3) {
177 return filename.substr(1, filename.size() - 2);