17template<
typename ValueType>
23 const std::regex commentRegex(
"(/\\*([^*]|(\\*+[^*/]))*\\*+/)|(//.*)");
30 std::string toplevelId =
"";
38 size_t commentEnd = line.find(
"*/");
39 if (commentEnd == std::string::npos) {
43 line = line.substr(commentEnd + 2);
48 line = std::regex_replace(line, commentRegex,
"");
50 size_t commentStart = line.find(
"/*");
51 if (commentStart != std::string::npos) {
53 line = line.substr(0, commentStart);
64 STORM_LOG_THROW(line.back() ==
';', storm::exceptions::WrongFormatException,
"Semicolon expected at the end of line " << lineNo <<
".");
69 std::vector<std::string> tokens;
70 boost::split(tokens, line, boost::is_any_of(
" \t"), boost::token_compress_on);
73 if (tokens[0] ==
"toplevel") {
75 STORM_LOG_THROW(toplevelId.empty(), storm::exceptions::WrongFormatException,
"Toplevel element already defined.");
76 STORM_LOG_THROW(tokens.size() == 2, storm::exceptions::WrongFormatException,
"Expected unique element id after 'toplevel'.");
77 toplevelId = parseName(tokens[1]);
78 }
else if (tokens[0] ==
"param") {
80 STORM_LOG_THROW(tokens.size() == 2, storm::exceptions::WrongFormatException,
"Expected unique parameter name after 'param'.");
81 STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException,
82 "Parameters are only allowed when using rational functions.");
86 std::string name = parseName(tokens[0]);
88 std::vector<std::string> childNames;
89 for (
size_t i = 2; i < tokens.size(); ++i) {
90 childNames.push_back(parseName(tokens[i]));
94 std::string type = tokens[1];
97 }
else if (type ==
"or") {
99 }
else if (boost::starts_with(type,
"vot")) {
100 size_t threshold = storm::parser::parseNumber<size_t>(type.substr(3));
102 }
else if (type.find(
"of") != std::string::npos) {
103 size_t pos = type.find(
"of");
104 size_t threshold = storm::parser::parseNumber<size_t>(type.substr(0, pos));
105 size_t count = storm::parser::parseNumber<size_t>(type.substr(pos + 2));
106 STORM_LOG_THROW(count == childNames.size(), storm::exceptions::WrongFormatException,
107 "Voting gate number " << count <<
" does not correspond to number of children " << childNames.size() <<
".");
109 }
else if (type ==
"pand") {
111 }
else if (type ==
"pand-incl" || type ==
"pand<=") {
113 }
else if (type ==
"pand-excl" || type ==
"pand<") {
115 }
else if (type ==
"por") {
117 }
else if (type ==
"por-incl" || type ==
"por<=") {
119 }
else if (type ==
"por-excl" || type ==
"por<") {
121 }
else if (type ==
"wsp" || type ==
"csp" || type ==
"hsp" || type ==
"spare") {
123 }
else if (type ==
"seq") {
125 }
else if (type ==
"mutex") {
127 }
else if (type ==
"fdep") {
128 builder.
addPdep(name, childNames, storm::utility::one<ValueType>());
129 }
else if (boost::starts_with(type,
"pdep=")) {
130 ValueType probability = valueParser.
parseValue(type.substr(5));
131 builder.
addPdep(name, childNames, probability);
132 }
else if (type.find(
"=") != std::string::npos) {
135 std::regex regexName(
"\"?" + tokens[0] +
"\"?");
136 std::string remaining_line = std::regex_replace(line, regexName,
"");
137 parseBasicElement(name, remaining_line, builder, valueParser);
138 }
else if (type.find(
"insp") != std::string::npos) {
140 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Inspections are not supported.");
142 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Type name '" << type <<
"' not recognized.");
147 STORM_LOG_THROW(
false, storm::exceptions::FileIoException,
"A parsing exception occurred in line " << lineNo <<
": " << exception.
what());
159template<
typename ValueType>
161 size_t firstQuots = name.find(
"\"");
162 if (firstQuots != std::string::npos) {
164 size_t secondQuots = name.find(
"\"", firstQuots + 1);
165 STORM_LOG_THROW(secondQuots != std::string::npos, storm::exceptions::WrongFormatException,
"No ending quotation mark found in " << name);
166 return name.substr(firstQuots + 1, secondQuots - 1);
172template<
typename ValueType>
173std::string DFTGalileoParser<ValueType>::parseValue(std::string name, std::string& line) {
175 std::regex nameRegex(name +
"\\s*=\\s*([^\\s]*)");
177 if (std::regex_search(line, match, nameRegex)) {
179 std::string value = match.str(1);
180 line = std::regex_replace(line, nameRegex,
"");
188template<
typename ValueType>
195 std::optional<BEType> distribution;
196 std::optional<ValueType> prob;
197 std::optional<ValueType> lambda;
198 std::optional<size_t> phases;
199 std::optional<ValueType> shape;
200 std::optional<ValueType> rate;
201 std::optional<ValueType> mean;
202 std::optional<ValueType> stddev;
203 std::optional<ValueType> dorm;
207 std::string value = parseValue(
"prob", input);
208 if (!value.empty()) {
210 distribution = BEType::PROBABILITY;
214 value = parseValue(
"lambda", input);
215 if (!value.empty()) {
217 !distribution.has_value(), storm::exceptions::WrongFormatException,
218 "Two distributions " <<
toString(distribution.value()) <<
" and " <<
toString(BEType::EXPONENTIAL) <<
" are defined for BE '" << name <<
"'.");
220 distribution = BEType::EXPONENTIAL;
225 value = parseValue(
"phases", input);
226 if (!value.empty()) {
228 !distribution.has_value() || distribution.value() == BEType::EXPONENTIAL, storm::exceptions::WrongFormatException,
229 "Two distributions " <<
toString(distribution.value()) <<
" and " <<
toString(BEType::ERLANG) <<
" are defined for BE '" << name <<
"'.");
230 phases = storm::parser::parseNumber<size_t>(value);
231 distribution = BEType::ERLANG;
235 value = parseValue(
"shape", input);
236 if (!value.empty()) {
238 !distribution.has_value(), storm::exceptions::WrongFormatException,
239 "Two distributions " <<
toString(distribution.value()) <<
" and " <<
toString(BEType::WEIBULL) <<
" are defined for BE '" << name <<
"'.");
241 distribution = BEType::WEIBULL;
243 value = parseValue(
"rate", input);
244 if (!value.empty()) {
246 !distribution.has_value() || distribution.value() == BEType::WEIBULL, storm::exceptions::WrongFormatException,
247 "Two distributions " <<
toString(distribution.value()) <<
" and " <<
toString(BEType::WEIBULL) <<
" are defined for BE '" << name <<
"'.");
252 value = parseValue(
"mean", input);
253 if (!value.empty()) {
255 !distribution.has_value(), storm::exceptions::WrongFormatException,
256 "Two distributions " <<
toString(distribution.value()) <<
" and " <<
toString(BEType::LOGNORMAL) <<
" are defined for BE '" << name <<
"'.");
258 distribution = BEType::LOGNORMAL;
260 value = parseValue(
"stddev", input);
261 if (!value.empty()) {
263 !distribution.has_value() || distribution.value() == BEType::LOGNORMAL, storm::exceptions::WrongFormatException,
264 "Two distributions " <<
toString(distribution.value()) <<
" and " <<
toString(BEType::LOGNORMAL) <<
" are defined for BE '" << name <<
"'.");
269 value = parseValue(
"dorm", input);
270 if (!value.empty()) {
275 value = parseValue(
"cov", input);
276 if (!value.empty()) {
277 STORM_LOG_WARN(
"Coverage is not supported and will be ignored for basic element '" << name <<
"'.");
279 value = parseValue(
"res", input);
280 if (!value.empty()) {
281 STORM_LOG_WARN(
"Restoration is not supported and will be ignored for basic element '" << name <<
"'.");
283 value = parseValue(
"repl", input);
284 if (!value.empty()) {
285 size_t replication = storm::parser::parseNumber<size_t>(value);
286 STORM_LOG_THROW(replication == 1, storm::exceptions::NotSupportedException,
"Replication > 1 is not supported for basic element '" << name <<
"'.");
288 value = parseValue(
"interval", input);
289 if (!value.empty()) {
290 STORM_LOG_WARN(
"Interval is not supported and will be ignored for basic element '" << name <<
"'.");
292 value = parseValue(
"repair", input);
293 if (!value.empty()) {
294 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Repairs are not supported and will be ignored for basic element '" << name <<
"'.");
299 STORM_LOG_THROW(
false, storm::exceptions::WrongFormatException,
"Unknown arguments for basic element '" << name <<
"': " << input);
303 STORM_LOG_THROW(distribution.has_value(), storm::exceptions::WrongFormatException,
"No failure distribution is defined for BE '" << name <<
"'.");
304 switch (distribution.value()) {
305 case BEType::PROBABILITY:
306 STORM_LOG_THROW(prob.has_value(), storm::exceptions::WrongFormatException,
307 "Distribution " <<
toString(BEType::PROBABILITY) <<
" requires parameter 'prob' for BE '" << name <<
"'.");
308 if (!dorm.has_value()) {
309 STORM_LOG_WARN(
"No dormancy factor was provided for basic element '" << name <<
"'. Assuming dormancy factor of 1.");
310 dorm = storm::utility::one<ValueType>();
314 case BEType::EXPONENTIAL:
315 STORM_LOG_THROW(lambda.has_value(), storm::exceptions::WrongFormatException,
316 "Distribution " <<
toString(BEType::EXPONENTIAL) <<
" requires parameter 'lambda' for BE '" << name <<
"'.");
317 if (!dorm.has_value()) {
318 STORM_LOG_WARN(
"No dormancy factor was provided for basic element '" << name <<
"'. Assuming dormancy factor of 1.");
319 dorm = storm::utility::one<ValueType>();
324 STORM_LOG_THROW(lambda.has_value(), storm::exceptions::WrongFormatException,
325 "Distribution " <<
toString(BEType::ERLANG) <<
" requires parameter 'lambda' for BE '" << name <<
"'.");
326 STORM_LOG_THROW(phases.has_value(), storm::exceptions::WrongFormatException,
327 "Distribution " <<
toString(BEType::ERLANG) <<
" requires parameter 'phases' for BE '" << name <<
"'.");
328 if (!dorm.has_value()) {
329 STORM_LOG_WARN(
"No dormancy factor was provided for basic element '" << name <<
"'. Assuming dormancy factor of 1.");
330 dorm = storm::utility::one<ValueType>();
334 case BEType::WEIBULL:
335 STORM_LOG_THROW(shape.has_value(), storm::exceptions::WrongFormatException,
336 "Distribution " <<
toString(BEType::WEIBULL) <<
" requires parameter 'shape' for BE '" << name <<
"'.");
337 STORM_LOG_THROW(rate.has_value(), storm::exceptions::WrongFormatException,
338 "Distribution " <<
toString(BEType::WEIBULL) <<
" requires parameter 'rate' for BE '" << name <<
"'.");
341 case BEType::LOGNORMAL:
342 STORM_LOG_THROW(mean.has_value(), storm::exceptions::WrongFormatException,
343 "Distribution " <<
toString(BEType::LOGNORMAL) <<
" requires parameter 'mean' for BE '" << name <<
"'.");
344 STORM_LOG_THROW(stddev.has_value(), storm::exceptions::WrongFormatException,
345 "Distribution " <<
toString(BEType::WEIBULL) <<
" requires parameter 'stddev' for BE '" << name <<
"'.");
349 STORM_LOG_THROW(
false, storm::exceptions::WrongFormatException,
"No distribution defined for basic element '" << name <<
"'.");
355template class DFTGalileoParser<double>;
356template class DFTGalileoParser<RationalFunction>;