21 #include "libmesh/parallel.h" 22 #include "libmesh/fparser.hh" 39 std::string func_text;
42 auto n_errs =
exp.errors.size();
47 std::vector<std::string> var_names;
48 auto ret = fp.ParseAndDeduceVariables(func_text, var_names);
51 exp.errors.push_back(hit::errormsg(n,
"fparse error: ", fp.ErrorMsg()));
56 std::vector<double> var_vals;
57 for (
auto & var : var_names)
61 while ((curr = curr->parent()))
63 auto src = curr->find(var);
64 if (src && src != n && src->type() == hit::NodeType::Field)
66 exp.used.push_back(hit::pathJoin({curr->fullpath(), var}));
67 var_vals.push_back(curr->param<
double>(var));
73 exp.errors.push_back(hit::errormsg(
74 n,
"\n no variable '", var,
"' found for use in function parser expression"));
77 if (
exp.errors.size() != n_errs)
81 ss << std::setprecision(17) << fp.Eval(var_vals.data());
84 n->setVal(n->val(), hit::Field::Kind::Float);
90 const std::list<std::string> & args,
91 hit::BraceExpander &
exp)
93 std::vector<std::string> argv;
94 argv.insert(argv.begin(), args.begin(), args.end());
99 n->setVal(n->val(), hit::Field::Kind::Float);
104 if (argv.size() != 4 || (argv.size() >= 3 && argv[2] !=
"->"))
106 exp.errors.push_back(
108 "units error: Expected 4 arguments ${units number from_unit -> to_unit} or " 109 "2 arguments ${units number unit}"));
116 if (!from_unit.conformsTo(to_unit))
118 exp.errors.push_back(hit::errormsg(n,
123 ") does not convert to ",
132 Real num = MooseUtils::convert<Real>(argv[0]);
135 std::stringstream ss;
136 ss << std::setprecision(17) << to_unit.convert(num, from_unit);
151 n->setVal(n->val(), hit::Field::Kind::Float);
156 const std::optional<std::vector<std::string>> & input_text)
158 _input_filenames(input_filenames),
159 _input_text(input_text),
160 _app_type(
std::string())
164 Parser::Parser(
const std::string & input_filename,
const std::optional<std::string> & input_text)
166 input_text ? std::optional<std::vector<std::string>>({*input_text})
167 : std::optional<std::vector<std::string>>())
174 std::string prefix = n->type() == hit::NodeType::Field ?
"parameter" :
"section";
176 if (
_have.count(fullpath) > 0)
178 auto existing =
_have[fullpath];
182 hit::errormsg(existing, prefix,
" '", fullpath,
"' supplied multiple times"));
185 errors.push_back(hit::errormsg(n, prefix,
" '", fullpath,
"' supplied multiple times"));
192 const std::string & ,
195 if (n->type() == hit::NodeType::Field)
201 const std::string & ,
204 const auto it =
_map.find(fullpath);
205 if (it !=
_map.end())
209 "' overrides the same parameter in ",
210 it->second->filename(),
212 it->second->line()));
217 const std::string & ,
220 auto actives = section->find(
"active");
221 auto inactives = section->find(
"inactive");
223 if (actives && inactives && actives->type() == hit::NodeType::Field &&
224 inactives->type() == hit::NodeType::Field && actives->parent() == inactives->parent())
227 hit::errormsg(section,
"'active' and 'inactive' parameters both provided in section"));
232 if (actives && actives->type() == hit::NodeType::Field && actives->parent() == section)
234 auto vars = section->param<std::vector<std::string>>(
"active");
235 std::string msg =
"";
236 for (
auto & var :
vars)
238 if (!section->find(var))
243 msg = msg.substr(0, msg.size() - 2);
244 errors.push_back(hit::errormsg(section,
245 "variables listed as active (",
249 "' not found in input"));
253 if (inactives && inactives->type() == hit::NodeType::Field && inactives->parent() == section)
255 auto vars = section->param<std::vector<std::string>>(
"inactive");
256 std::string msg =
"";
257 for (
auto & var :
vars)
259 if (!section->find(var))
264 msg = msg.substr(0, msg.size() - 2);
265 errors.push_back(hit::errormsg(section,
266 "variables listed as inactive (",
270 "' not found in input"));
279 walk(
const std::string & ,
const std::string & , hit::Node * n)
override 281 if (n && n->type() == hit::NodeType::Field && n->fullpath() ==
"Application/type")
294 mooseError(
"Parser::getLastInputFileName(): No inputs are set");
304 mooseError(
"Input text is not the same size as the input filenames");
314 std::vector<std::string> dw_errmsg;
317 const std::string use_rel_paths_str =
318 std::getenv(
"MOOSE_RELATIVE_FILEPATHS") ? std::getenv(
"MOOSE_RELATIVE_FILEPATHS") :
"false";
319 const auto use_real_paths = use_rel_paths_str ==
"0" || use_rel_paths_str ==
"false";
324 const auto corrected_filename =
331 input = (*_input_text)[i];
335 std::ifstream f(corrected_filename);
336 input = std::string((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
343 std::stringstream input_errors;
344 std::unique_ptr<hit::Node>
root(hit::parse(corrected_filename, input, &input_errors));
345 hit::explode(
root.get());
347 root->walk(&dw, hit::NodeType::Field);
352 root->walk(&opw, hit::NodeType::Field);
356 if (!input_errors.str().empty())
357 throw hit::ParseError(input_errors.str());
359 for (
auto & msg : dw.errors)
360 errmsg += msg +
"\n";
362 dw_errmsg.push_back(errmsg);
363 _root->walk(&cpw, hit::NodeType::Field);
365 catch (hit::ParseError &
err)
378 _root->walk(&bw, hit::NodeType::Section);
381 _root->walk(&fw, hit::NodeType::Field);
385 for (
auto & msg : bw.
errors)
386 errmsg += msg +
"\n";
389 if (errmsg.size() > 0)
392 for (
auto & msg : dw_errmsg)
const std::vector< std::string > _input_filenames
The input file names.
void setAppType(const std::string &app_type)
void parse()
Parses the inputs.
const std::optional< std::vector< std::string > > _input_text
The optional input text contents (to support not reading by file)
std::vector< std::string > errors
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
virtual std::string eval(hit::Field *n, const std::list< std::string > &args, hit::BraceExpander &exp)
void walk(const std::string &, const std::string &, hit::Node *n) override
const std::string & getLastInputFileName() const
void mooseInfoRepeated(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
const std::vector< std::string > & getInputFileNames() const
std::vector< std::string > warnings
std::string realpath(const std::string &path)
Wrapper around PetscGetRealPath, which is a cross-platform replacement for realpath.
std::set< std::string > _duplicates
virtual void walk(const std::string &fullpath, const std::string &, hit::Node *n) override
void mooseInfo(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
Parser(const std::vector< std::string > &input_filenames, const std::optional< std::vector< std::string >> &input_text={})
Constructor given a list of input files, given in input_filenames.
std::map< std::string, hit::Node * > _have
constexpr auto merge(std::index_sequence< first... >, std::index_sequence< second... >)
Merge two index sequences into one.
bool checkFileReadable(const std::string &filename, bool check_line_endings=false, bool throw_on_unreadable=true, bool check_for_git_lfs_pointer=true)
Checks to see if a file is readable (exists and permissions)
std::string stringify(const T &t)
conversion to string
std::map< std::string, hit::Node * > ParamMap
Physical unit management class with runtime unit string parsing, unit checking, unit conversion...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const std::optional< std::string > & getApp()
virtual void walk(const std::string &fullpath, const std::string &, hit::Node *n) override
std::unique_ptr< hit::Node > _root
The root node, which owns the whole tree.
void walk(const std::string &fullpath, const std::string &, hit::Node *n) override
std::optional< std::string > _app_type
virtual std::string eval(hit::Field *n, const std::list< std::string > &args, hit::BraceExpander &exp)
auto index_range(const T &sizable)
Class for parsing input files.
std::vector< std::string > errors
virtual void walk(const std::string &, const std::string &, hit::Node *section) override
const CompileParamWalker::ParamMap & _map