https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Parser.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10// MOOSE includes
11#include "MooseUtils.h"
12#include "MooseInit.h"
13#include "MooseTypes.h"
14#include "CommandLine.h"
15#include "SystemInfo.h"
16#include "Parser.h"
17#include "Units.h"
18
19#include "libmesh/parallel.h"
20#include "libmesh/fparser.hh"
21
22// C++ includes
23#include <map>
24#include <fstream>
25#include <algorithm>
26#include <cstdlib>
27
28std::string
29FuncParseEvaler::eval(hit::Field * n, const std::list<std::string> & args, hit::BraceExpander & exp)
30{
31 std::string func_text;
32 for (auto & s : args)
33 func_text += s;
34 auto n_errs = exp.errors.size();
35
36 FunctionParser fp;
37 fp.AddConstant("pi", libMesh::pi);
38 fp.AddConstant("e", std::exp(Real(1)));
39 std::vector<std::string> var_names;
40 auto ret = fp.ParseAndDeduceVariables(func_text, var_names);
41 if (ret != -1)
42 {
43 exp.errors.emplace_back(
44 "fparse error: " + std::string(fp.ErrorMsg()) + " in '" + n->fullpath() + "'", n);
45 return n->val();
46 }
47
48 std::vector<double> var_vals;
49 for (auto & var : var_names)
50 {
51 // recursively check all parent scopes for the needed variables
52 hit::Node * curr = n;
53 while ((curr = curr->parent()))
54 {
55 auto src = curr->find(var);
56 if (src && src != n && src->type() == hit::NodeType::Field)
57 {
58 exp.used.push_back(hit::pathJoin({curr->fullpath(), var}));
59 var_vals.push_back(curr->param<double>(var));
60 break;
61 }
62 }
63
64 if (curr == nullptr)
65 exp.errors.emplace_back("no variable '" + var +
66 "' found for use in function parser expression in '" +
67 n->fullpath() + "'",
68 n);
69 }
70
71 if (exp.errors.size() != n_errs)
72 return n->val();
73
74 std::stringstream ss;
75 ss << std::setprecision(17) << fp.Eval(var_vals.data());
76
77 // change kind only (not val)
78 n->setVal(n->val(), hit::Field::Kind::Float);
79 return ss.str();
80}
81
82std::string
84 const std::list<std::string> & args,
85 hit::BraceExpander & exp)
86{
87 std::vector<std::string> argv;
88 argv.insert(argv.begin(), args.begin(), args.end());
89
90 // no conversion, the expression currently only documents the units and passes through the value
91 if (argv.size() == 2)
92 {
93 n->setVal(n->val(), hit::Field::Kind::Float);
94 return argv[0];
95 }
96
97 // conversion
98 if (argv.size() != 4 || (argv.size() >= 3 && argv[2] != "->"))
99 {
100 exp.errors.emplace_back("units error: Expected 4 arguments ${units number from_unit -> "
101 "to_unit} or 2 arguments ${units number unit} in '" +
102 n->fullpath() + "'",
103 n);
104 return n->val();
105 }
106
107 // get and check units
108 auto from_unit = MooseUnits(argv[1]);
109 auto to_unit = MooseUnits(argv[3]);
110 if (!from_unit.conformsTo(to_unit))
111 {
112 std::ostringstream err;
113 err << "units error: " << argv[1] << " (" << from_unit << ") does not convert to " << argv[3]
114 << " (" << to_unit << ") in '" << n->fullpath() << "'";
115 exp.errors.emplace_back(err.str(), n);
116 return n->val();
117 }
118
119 // parse number
120 Real num = MooseUtils::convert<Real>(argv[0]);
121
122 // convert units
123 std::stringstream ss;
124 ss << std::setprecision(17) << to_unit.convert(num, from_unit);
125
126#ifndef NDEBUG
127 mooseInfoRepeated(n->filename() + ':' + Moose::stringify(n->line()) + ':' +
128 Moose::stringify(n->column()) + ": Unit conversion ",
129 num,
130 ' ',
131 argv[1],
132 " -> ",
133 ss.str(),
134 ' ',
135 argv[3]);
136#endif
137
138 // change kind only (not val)
139 n->setVal(n->val(), hit::Field::Kind::Float);
140 return ss.str();
141}
142
143std::string
144EnumerateEvaler::eval(hit::Field * n, const std::list<std::string> & args, hit::BraceExpander & exp)
145{
146 std::vector<std::string> argv;
147 argv.insert(argv.begin(), args.begin(), args.end());
148
149 if (argv.size() != 3)
150 {
151 exp.errors.emplace_back(
152 "enumerate error: Expected 3 arguments ${enumerate prefix first_index last_index} in '" +
153 n->fullpath() + "'",
154 n);
155 return n->val();
156 }
157
158 const auto & prefix = argv[0];
159 std::array<int, 2> index;
160 for (const auto i : make_range(2))
161 {
162 const auto & arg = argv[i + 1];
163 if (arg.empty() || arg.find_first_not_of("0123456789") != std::string::npos)
164 {
165 exp.errors.emplace_back("enumerate error: index '" + arg +
166 "' is not a non-negative integer in '" + n->fullpath() + "'",
167 n);
168 return n->val();
169 }
170 index[i] = MooseUtils::convert<int>(arg);
171 }
172
173 if (index[1] < index[0])
174 {
175 exp.errors.emplace_back("enumerate error: last index " + argv[2] +
176 " is smaller than first index " + argv[1] + " in '" +
177 n->fullpath() + "'",
178 n);
179 return n->val();
180 }
181
182 std::vector<std::string> names;
183 for (const auto i : make_range(index[0], index[1] + 1))
184 names.push_back(prefix + std::to_string(i));
185
186 return MooseUtils::stringJoin(names);
187}
188
189std::string
190RangeEvaler::eval(hit::Field * n, const std::list<std::string> & args, hit::BraceExpander & exp)
191{
192 std::vector<std::string> argv;
193 argv.insert(argv.begin(), args.begin(), args.end());
194
195 if (argv.size() < 2 || argv.size() > 3)
196 {
197 exp.errors.emplace_back("range error: Expected either 2 arguments '${range start stop}' "
198 "or 3 arguments '${range start stop step}' in '" +
199 n->fullpath() + "'",
200 n);
201 return n->val();
202 }
203
204 std::array<int, 3> int_args;
205 for (const auto i : make_range(argv.size()))
206 {
207 bool success = false;
208 if (!argv[i].empty())
209 success = MooseUtils::convert(argv[i], int_args[i], false);
210
211 if (!success)
212 {
213 exp.errors.emplace_back("range error: parameter '" + argv[i] + "' is not an integer in '" +
214 n->fullpath() + "'",
215 n);
216 return n->val();
217 }
218 }
219 if (argv.size() == 2)
220 int_args[2] = 1;
221
222 if (int_args[2] == 0)
223 {
224 exp.errors.emplace_back("range error: step is zero in '" + n->fullpath() + "'", n);
225 return n->val();
226 }
227
228 std::vector<std::string> names;
229 if (int_args[2] > 0)
230 {
231 if (int_args[1] < int_args[0])
232 {
233 exp.errors.emplace_back("range error: end point '" + argv[1] +
234 "' is smaller than the start point '" + argv[0] +
235 "' when the step is positive in '" + n->fullpath() + "'",
236 n);
237 return n->val();
238 }
239
240 for (int i = int_args[0]; i < int_args[1]; i += int_args[2])
241 names.push_back(std::to_string(i));
242 }
243 else
244 {
245 if (int_args[0] < int_args[1])
246 {
247 exp.errors.emplace_back("range error: start point '" + argv[0] +
248 "' is smaller than the end point '" + argv[1] +
249 "' when the step is negative in '" + n->fullpath() + "'",
250 n);
251 return n->val();
252 }
253
254 for (int i = int_args[0]; i > int_args[1]; i += int_args[2])
255 names.push_back(std::to_string(i));
256 }
257
258 return MooseUtils::stringJoin(names);
259}
260
261std::string
262RepeatEvaler::eval(hit::Field * n, const std::list<std::string> & args, hit::BraceExpander & exp)
263{
264 std::vector<std::string> argv;
265 argv.insert(argv.begin(), args.begin(), args.end());
266
267 if (argv.size() != 2)
268 {
269 exp.errors.emplace_back(
270 "repeat error: Expected 2 arguments ${repeat name count} in '" + n->fullpath() + "'", n);
271 return n->val();
272 }
273
274 const auto & count_arg = argv[1];
275 if (count_arg.empty() || count_arg.find_first_not_of("0123456789") != std::string::npos)
276 {
277 exp.errors.emplace_back("repeat error: count '" + count_arg +
278 "' is not a non-negative integer in '" + n->fullpath() + "'",
279 n);
280 return n->val();
281 }
282
283 const std::vector<std::string> values(MooseUtils::convert<int>(count_arg), argv[0]);
285}
286
287Parser::Parser(const std::vector<std::string> & input_filenames,
288 const std::optional<std::vector<std::string>> & input_text /* = {} */)
289 : _root(nullptr),
290 _input_filenames(input_filenames),
291 _input_text(input_text ? *input_text : std::vector<std::string>()),
292 _cli_root(nullptr),
293 _throw_on_error(false)
294{
295 if (input_text && _input_filenames.size() != input_text->size())
296 mooseError("Parser: Input text not the same length as input filenames");
297}
298
299Parser::Parser(const std::string & input_filename,
300 const std::optional<std::string> & input_text /* = {} */)
301 : Parser(std::vector<std::string>{input_filename},
302 input_text ? std::optional<std::vector<std::string>>({*input_text})
303 : std::optional<std::vector<std::string>>())
304{
305}
306
307void
308DupParamWalker::walk(const std::string & fullpath, const std::string & /*nodepath*/, hit::Node * n)
309{
310 const auto it = _have.try_emplace(fullpath, n);
311 if (!it.second)
312 {
313 const std::string type = n->type() == hit::NodeType::Field ? "parameter" : "section";
314 const std::string error = type + " '" + fullpath + "' supplied multiple times";
315
316 // Don't warn multiple times (will happen if we find it three+ times)
317 const auto existing = it.first->second;
318 if (std::find_if(errors.begin(),
319 errors.end(),
320 [&existing](const auto & err)
321 { return err.node == existing; }) == errors.end())
322 errors.emplace_back(error, existing);
323
324 errors.emplace_back(error, n);
325 }
326}
327
328void
329CompileParamWalker::walk(const std::string & fullpath,
330 const std::string & /*nodepath*/,
331 hit::Node * n)
332{
333 if (n->type() == hit::NodeType::Field)
334 _map[fullpath] = n;
335}
336
337void
338OverrideParamWalker::walk(const std::string & fullpath,
339 const std::string & /*nodepath*/,
340 hit::Node * n)
341{
342 const auto it = _map.find(fullpath);
343 if (it != _map.end())
344 warnings.push_back(hit::errormsg(n,
345 " Parameter '",
346 fullpath,
347 "' overrides the same parameter in ",
348 it->second->filename(),
349 ":",
350 it->second->line()));
351}
352
353void
354BadActiveWalker ::walk(const std::string & fullpath,
355 const std::string & /*nodepath*/,
356 hit::Node * section)
357{
358 auto actives = section->find("active");
359 auto inactives = section->find("inactive");
360
361 if (actives && inactives && actives->type() == hit::NodeType::Field &&
362 inactives->type() == hit::NodeType::Field && actives->parent() == inactives->parent())
363 {
364 errors.emplace_back(
365 "'active' and 'inactive' parameters both provided in section '" + fullpath + "'", section);
366 return;
367 }
368
369 // ensures we don't recheck deeper nesting levels
370 if (actives && actives->type() == hit::NodeType::Field && actives->parent() == section)
371 {
372 auto vars = section->param<std::vector<std::string>>("active");
373 std::string msg = "";
374 for (auto & var : vars)
375 {
376 if (!section->find(var))
377 msg += var + ", ";
378 }
379 if (msg.size() > 0)
380 {
381 msg = msg.substr(0, msg.size() - 2);
382 errors.emplace_back("variables listed as active (" + msg + ") in section '" +
383 section->fullpath() + "' not found in input",
384 section);
385 }
386 }
387 // ensures we don't recheck deeper nesting levels
388 if (inactives && inactives->type() == hit::NodeType::Field && inactives->parent() == section)
389 {
390 auto vars = section->param<std::vector<std::string>>("inactive");
391 std::string msg = "";
392 for (auto & var : vars)
393 {
394 if (!section->find(var))
395 msg += var + ", ";
396 }
397 if (msg.size() > 0)
398 {
399 msg = msg.substr(0, msg.size() - 2);
400 errors.emplace_back("variables listed as inactive (" + msg + ") in section '" +
401 section->fullpath() + "' not found in input",
402 section);
403 }
404 }
405}
406
407class FindAppWalker : public hit::Walker
408{
409public:
410 void
411 walk(const std::string & /*fullpath*/, const std::string & /*nodepath*/, hit::Node * n) override
412 {
413 if (n && n->type() == hit::NodeType::Field && n->fullpath() == "Application/type")
414 _app_type = n->param<std::string>();
415 }
416 const std::optional<std::string> & getApp() { return _app_type; };
417
418private:
419 std::optional<std::string> _app_type;
420};
421
422void
423Parser::setCommandLineParams(const std::vector<std::string> & params)
424{
425 mooseAssert(!_command_line_params, "Already set");
426 _command_line_params = params;
427}
428
429const std::string &
431{
432 if (_input_filenames.empty())
433 mooseError("Parser::getLastInputFileName(): No inputs are set");
434 return _input_filenames.back();
435}
436
437Parser::Error::Error(const std::vector<hit::ErrorMessage> & error_messages)
438 : hit::Error(error_messages)
439{
440}
441
442void
444{
445 mooseAssert(!_root && !_cli_root, "Has already parsed");
446
447 if (getInputFileNames().size() > 1)
448 mooseInfo("Merging inputs ", Moose::stringify(getInputFileNames()));
449
450 // Correct filenames (default is to use real path)
451 const std::string use_rel_paths_str =
452 std::getenv("MOOSE_RELATIVE_FILEPATHS") ? std::getenv("MOOSE_RELATIVE_FILEPATHS") : "false";
453 const auto use_real_paths = use_rel_paths_str == "0" || use_rel_paths_str == "false";
454 std::vector<std::string> filenames;
455 for (const auto & filename : getInputFileNames())
456 filenames.push_back(use_real_paths ? MooseUtils::realpath(filename) : filename);
457
458 // Load each input file if text was not provided
459 if (_input_text.empty())
460 for (const auto & filename : filenames)
461 {
462 MooseUtils::checkFileReadable(filename, true);
463 std::ifstream f(filename);
464 _input_text.push_back(
465 std::string((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>()));
466 }
467
468 CompileParamWalker::ParamMap override_map;
469 CompileParamWalker cpw(override_map);
470 OverrideParamWalker opw(override_map);
471
472 // Errors from the duplicate param walker, ran within each input
473 // independently first
474 std::vector<hit::ErrorMessage> dw_errors;
475
476 for (const auto i : index_range(getInputFileNames()))
477 {
478 const auto & filename = filenames[i];
479 const auto & input = getInputText()[i];
480
481 try
482 {
483 // provide stream to hit parse function to capture any syntax errors,
484 // set parser root node, then throw those errors if any were captured
485 std::vector<hit::ErrorMessage> syntax_errors;
486 std::unique_ptr<hit::Node> root(hit::parse(filename, input, &syntax_errors));
487
489 root->walk(&dw, hit::NodeType::Field);
490 appendErrorMessages(dw_errors, dw.errors);
491
492 if (!queryRoot())
493 _root = std::move(root);
494 else
495 {
496 root->walk(&opw, hit::NodeType::Field);
497 hit::merge(root.get(), &getRoot());
498 }
499
500 if (!syntax_errors.empty())
501 throw Parser::Error(syntax_errors);
502
503 getRoot().walk(&cpw, hit::NodeType::Field);
504 }
505 catch (hit::Error & err)
506 {
507 parseError(err.error_messages);
508 }
509 }
510
511 // warn about overridden parameters in multiple inputs
512 if (!opw.warnings.empty())
514
515 // If we don't have a root (allow no input files),
516 // create an empty one
517 if (!queryRoot())
518 _root.reset(hit::parse("EMPTY", ""));
519
520 {
522 getRoot().walk(&bw, hit::NodeType::Section);
523 if (bw.errors.size())
524 parseError(bw.errors);
525 }
526
527 {
528 FindAppWalker fw;
529 getRoot().walk(&fw, hit::NodeType::Field);
530 if (fw.getApp())
531 setAppType(*fw.getApp());
532 }
533
534 // Duplicate parameter errors (within each input file)
535 if (dw_errors.size())
536 parseError(dw_errors);
537
538 // Merge in command line HIT arguments
539 const auto joined_params =
541 try
542 {
543 _cli_root.reset(hit::parse("CLI_ARGS", joined_params));
544 hit::merge(&getCommandLineRoot(), &getRoot());
545 }
546 catch (hit::Error & err)
547 {
548 parseError(err.error_messages);
549 }
550
551 std::vector<hit::ErrorMessage> errors;
552
553 // expand ${bla} parameter values and mark/include variables
554 // used in expansion as "used" (obtained later by the Builder
555 // with getExtractedVars())
556 {
557 hit::RawEvaler raw;
558 hit::EnvEvaler env;
559 hit::ReplaceEvaler repl;
560 FuncParseEvaler fparse_ev;
561 UnitsConversionEvaler units_ev;
562 EnumerateEvaler enumerate_ev;
563 RangeEvaler range_ev;
564 RepeatEvaler repeat_ev;
565 hit::BraceExpander exw;
566 exw.registerEvaler("raw", raw);
567 exw.registerEvaler("env", env);
568 exw.registerEvaler("fparse", fparse_ev);
569 exw.registerEvaler("replace", repl);
570 exw.registerEvaler("units", units_ev);
571 exw.registerEvaler("enumerate", enumerate_ev);
572 exw.registerEvaler("range", range_ev);
573 exw.registerEvaler("repeat", repeat_ev);
574 getRoot().walk(&exw);
575 for (auto & var : exw.used)
576 _extracted_vars.insert(var);
577 Parser::appendErrorMessages(errors, exw.errors);
578 }
579
580 // Collect duplicate parameters now that we've merged inputs
581 {
583 getRoot().walk(&dw, hit::NodeType::Field);
585 }
586
587 // Check bad active now that we've merged inputs
588 {
590 getRoot().walk(&bw, hit::NodeType::Section);
592 }
593
594 if (errors.size())
595 parseError(errors);
596}
597
598hit::Node &
600{
601 if (!queryRoot())
602 mooseError("Parser::getRoot(): root is not set");
603 return *queryRoot();
604}
605
606const hit::Node &
608{
610 mooseError("Parser::getCommandLineRoot(): command line root is not set");
611 return *queryCommandLineRoot();
612}
613
614hit::Node &
616{
617 return const_cast<hit::Node &>(std::as_const(*this).getCommandLineRoot());
618}
619
620void
621Parser::appendErrorMessages(std::vector<hit::ErrorMessage> & to,
622 const std::vector<hit::ErrorMessage> & from)
623{
624 to.insert(to.end(), from.begin(), from.end());
625}
626
627void
628Parser::appendErrorMessages(std::vector<hit::ErrorMessage> & to, const hit::Error & error)
629{
630 appendErrorMessages(to, error.error_messages);
631}
632
633std::string
634Parser::joinErrorMessages(const std::vector<hit::ErrorMessage> & error_messages)
635{
636 std::vector<std::string> values;
637 for (const auto & em : error_messages)
638 values.push_back(em.prefixed_message);
639 return MooseUtils::stringJoin(values, "\n");
640}
641
642void
643Parser::parseError(std::vector<hit::ErrorMessage> messages) const
644{
645 // Few things about command line arguments...
646 // 1. We don't care to add line and column context for CLI args, because
647 // it doesn't make sense. We go from the full CLI args and pull out
648 // the HIT parameters so "line" 1 might not even be command line
649 // argument 1. So, remove line/column context from all CLI args.
650 // 2. Whenever we have a parameter in input that then gets overridden
651 // by a command line argument, under the hood we're merging two
652 // different HIT trees. However, WASP doesn't currently update the
653 // "filename" context for the updated parameter. Which means that
654 // a param that is in input and then overridden by CLI will have
655 // its location as in input. Which isn't true. So we get around this
656 // by searching the independent CLI args tree for params that we have
657 // errors for. If the associated path is also in CLI args, we manually
658 // set its error to come from CLI args. This should be fixed in
659 // the future with a WASP update.
660 for (auto & em : messages)
661 if (em.node && queryCommandLineRoot())
662 if (getCommandLineRoot().find(em.node->fullpath()))
663 em = hit::ErrorMessage(em.message, "CLI_ARGS");
664
665 if (_throw_on_error)
666 throw Parser::Error(messages);
667 else
668 mooseError(joinErrorMessages(messages));
669}
void mooseInfoRepeated(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
Definition MooseError.h:409
void mooseInfo(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
Definition MooseError.h:401
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
std::array< Real, 2 > values
Definition MortarUtils.C:52
char ** vars
std::vector< hit::ErrorMessage > errors
Definition Parser.h:75
virtual void walk(const std::string &, const std::string &, hit::Node *section) override
Definition Parser.C:354
std::map< std::string, hit::Node * > ParamMap
Definition Parser.h:81
virtual void walk(const std::string &fullpath, const std::string &, hit::Node *n) override
Definition Parser.C:329
ParamMap & _map
Definition Parser.h:88
std::map< std::string, hit::Node * > _have
Definition Parser.h:66
virtual void walk(const std::string &fullpath, const std::string &, hit::Node *n) override
Definition Parser.C:308
std::vector< hit::ErrorMessage > errors
Definition Parser.h:63
virtual std::string eval(hit::Field *n, const std::list< std::string > &args, hit::BraceExpander &exp)
Definition Parser.C:144
std::optional< std::string > _app_type
Definition Parser.C:419
const std::optional< std::string > & getApp()
Definition Parser.C:416
void walk(const std::string &, const std::string &, hit::Node *n) override
Definition Parser.C:411
virtual std::string eval(hit::Field *n, const std::list< std::string > &args, hit::BraceExpander &exp)
Definition Parser.C:29
Physical unit management class with runtime unit string parsing, unit checking, unit conversion,...
Definition Units.h:33
const CompileParamWalker::ParamMap & _map
Definition Parser.h:100
std::vector< std::string > warnings
Definition Parser.h:97
void walk(const std::string &fullpath, const std::string &, hit::Node *n) override
Definition Parser.C:338
Class for parsing input files.
Definition Parser.h:109
std::set< std::string > _extracted_vars
Variables that have been extracted during brace expansion.
Definition Parser.h:273
static void appendErrorMessages(std::vector< hit::ErrorMessage > &to, const std::vector< hit::ErrorMessage > &from)
Helper for accumulating errors from a walker into an accumulation of errors.
Definition Parser.C:621
const std::string & getLastInputFileName() const
Definition Parser.C:430
void setAppType(const std::string &app_type)
Definition Parser.h:191
const hit::Node & getCommandLineRoot() const
Definition Parser.C:607
const hit::Node * queryRoot() const
Definition Parser.h:142
void setCommandLineParams(const std::vector< std::string > &params)
Sets the HIT parameters from the command line.
Definition Parser.C:423
const std::vector< std::string > & getInputText() const
Definition Parser.h:181
std::vector< std::string > _input_text
The input text (may be filled during parse())
Definition Parser.h:258
const std::vector< std::string > & getInputFileNames() const
Definition Parser.h:176
const std::vector< std::string > _input_filenames
The input file names.
Definition Parser.h:255
std::optional< std::vector< std::string > > _command_line_params
The command line HIT parameters (if any)
Definition Parser.h:270
std::unique_ptr< hit::Node > _cli_root
The root node for command line hit arguments.
Definition Parser.h:261
std::unique_ptr< hit::Node > _root
The root node, which owns the whole tree.
Definition Parser.h:252
void parseError(std::vector< hit::ErrorMessage > messages) const
Helper for throwing an error with the given messages.
Definition Parser.C:643
bool _throw_on_error
Whether or not to throw on error.
Definition Parser.h:267
hit::Node & getRoot()
Definition Parser.C:599
const hit::Node * queryCommandLineRoot() const
Definition Parser.h:159
void parse()
Parses the inputs.
Definition Parser.C:443
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.
Definition Parser.C:287
static std::string joinErrorMessages(const std::vector< hit::ErrorMessage > &error_messages)
Helper for combining error messages into a single, newline separated message.
Definition Parser.C:634
virtual std::string eval(hit::Field *n, const std::list< std::string > &args, hit::BraceExpander &exp)
Definition Parser.C:190
virtual std::string eval(hit::Field *n, const std::list< std::string > &args, hit::BraceExpander &exp)
Definition Parser.C:262
virtual std::string eval(hit::Field *n, const std::list< std::string > &args, hit::BraceExpander &exp)
Definition Parser.C:83
bool convert(const std::string &str, T &value, const bool throw_on_failure)
Takes the string representation of a value and converts it to the value.
std::string realpath(const std::string &path)
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
bool checkFileReadable(const std::string &filename, bool check_line_endings, bool throw_on_unreadable, bool check_for_git_lfs_pointer)
Definition MooseUtils.C:317
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:65
Definition Moose.h:48
const Real pi
Error()=delete