27 Reactions <- (_ Reaction _ Newline?)* _ 28 Reaction <- TermList _ '->' _ TermList _ Metadata? 29 TermList <- Term (_ Term)* 30 Term <- Coefficient? Species 32 Float <- [+-]? (_)? ([0-9]+)? ('.' [0-9]+)? 33 Species <- BaseSpecies State? Charge? 34 BaseSpecies <- [a-zA-Z][a-zA-Z0-9_]* 35 State <- '(' [a-z]{1,3} ')' 36 Charge <- ('^'? [0-9]* [+-]) 37 Metadata <- '[' _ Pair (_ ',' _ Pair)* _ ']' 38 Pair <- Key _ '=' _ Value 39 Key <- [A-Za-z_][A-Za-z0-9_]* 40 Value <- [A-Za-z0-9_.-]+ 44 mooseAssert(parser, "Failed to build parser");
47 parser[
"Reactions"] = [](
const SemanticValues & vs)
49 std::vector<Reaction> reactions;
50 for (
const auto &
v : vs)
54 reactions.push_back(std::any_cast<Reaction>(
v));
60 parser[
"Float"] = [](
const SemanticValues & vs)
63 std::string vs_str = std::string(std::any_cast<std::string_view>(vs.token()));
64 vs_str.erase(std::remove(vs_str.begin(), vs_str.end(),
' '), vs_str.end());
67 else if (vs_str ==
"+" || vs_str ==
"")
70 return std::stod(std::string(vs_str));
73 parser[
"Coefficient"] = [](
const SemanticValues & vs) {
return std::any_cast<
double>(vs[0]); };
75 parser[
"BaseSpecies"] = [](
const SemanticValues & vs) {
return vs.token(); };
77 parser[
"State"] = [](
const SemanticValues & vs) {
return vs.token(); };
79 parser[
"Charge"] = [](
const SemanticValues & vs) {
return vs.token(); };
81 parser[
"Species"] = [](
const SemanticValues & vs)
83 std::string base = std::string(std::any_cast<std::string_view>(vs[0]));
84 std::optional<std::string> state;
85 std::optional<std::string> charge;
90 for (
size_t i = 1; i < vs.size(); ++i)
91 if (vs[i].type() ==
typeid(std::string_view))
93 std::string val = std::string(std::any_cast<std::string_view>(vs[i]));
94 if (val.front() ==
'(' && val.back() ==
')')
101 return Term{1.0, base, state, charge};
104 parser[
"Term"] = [](
const SemanticValues & vs)
106 mooseAssert(vs.size() <= 2,
"Should only have a coefficient and a species");
109 double coeff = std::any_cast<
double>(vs[0]);
110 Term term = std::any_cast<Term>(vs[1]);
111 term.coefficient = coeff;
115 return std::any_cast<Term>(vs[0]);
118 parser[
"TermList"] = [](
const SemanticValues & vs)
121 for (
const auto &
v : vs)
124 if (
v.type() ==
typeid(Term))
125 terms.push_back(std::any_cast<Term>(
v));
127 else if (
v.type() ==
typeid(std::vector<Term>))
129 const auto & more = std::any_cast<std::vector<Term>>(
v);
130 terms.insert(terms.end(), more.begin(), more.end());
137 parser[
"Key"] = [](
const SemanticValues & vs) {
return vs.token(); };
139 parser[
"Value"] = [](
const SemanticValues & vs) {
return vs.token(); };
141 parser[
"Pair"] = [](
const SemanticValues & vs)
143 mooseAssert(vs.size() == 2,
"Metadata entry should have exactly one key and one value");
144 return std::make_pair(std::string(std::any_cast<std::string_view>(vs[0])),
145 std::string(std::any_cast<std::string_view>(vs[1])));
148 parser[
"Metadata"] = [](
const SemanticValues & vs)
151 for (
const auto &
v : vs)
153 if (
v.type() ==
typeid(std::pair<std::string, std::string>))
155 const auto & [
k, val] = std::any_cast<std::pair<std::string, std::string>>(
v);
158 else if (
v.type() ==
typeid(std::vector<std::pair<std::string, std::string>>))
160 const auto & pairs = std::any_cast<std::vector<std::pair<std::string, std::string>>>(
v);
161 for (
const auto & [
k, val] : pairs)
168 parser[
"Reaction"] = [](
const SemanticValues & vs)
171 if (vs.size() != 2 && vs.size() != 3)
172 mooseError(
"Reaction failed to read as 'reactors -> products [metadata]");
173 r.reactants = std::any_cast<
TermList>(vs[0]);
174 r.products = std::any_cast<
TermList>(vs[1]);
176 r.metadata = std::any_cast<Metadata>(vs[2]);
180 parser.enable_packrat_parsing();
182 std::vector<Reaction> reactions;
183 if (!parser.parse(reaction_network_string, reactions))
189 for (
size_t i = 0; i < reactions.size(); ++i)
191 const auto & r = reactions[i];
192 Moose::out <<
"Reaction " << i + 1 <<
":\n";
std::vector< Term > TermList
std::map< std::string, std::string > Metadata
void mooseError(Args &&... args)
std::string stringify(const T &t)
static const std::string k