62 std::string remove_trailing_whitespace(std::string
const& in) {
63 std::size_t new_end = 0;
64 for (std::size_t ri = 0; ri < in.size(); ++ri) {
65 std::size_t i = in.size() - 1 - ri;
66 if (in[i] !=
' ' && in[i] !=
'\t') {
71 return in.substr(0, new_end);
74 std::string remove_trailing_whitespace_and_newlines(std::string
const& in) {
75 std::size_t new_end = 0;
76 for (std::size_t ri = 0; ri < in.size(); ++ri) {
77 std::size_t i = in.size() - 1 - ri;
78 if (in[i] !=
' ' && in[i] !=
'\t' && in[i] !=
'\n' && in[i] !=
'\r') {
83 return in.substr(0, new_end);
87 bool is_parseable_as(std::string
const& text) {
88 std::istringstream ss(text);
90 ss >> std::noskipws >> val;
91 return ss.eof() && !ss.fail();
95 bool is_parseable_as<int>(std::string
const& text) {
96 std::istringstream ss(text);
99 ss >> std::noskipws >> val;
100 return ss.eof() && !ss.fail() &&
101 (val >= LL(std::numeric_limits<int>::min())) &&
102 (val <= LL(std::numeric_limits<int>::max()));
105 template <
typename T>
106 T parse_as(std::string
const& text) {
107 std::istringstream ss(text);
114 static char my_tolower(
char ch)
116 return std::tolower(static_cast<unsigned char>(ch));
120 static bool my_isdigit(
char ch)
122 return std::isdigit(static_cast<unsigned char>(ch));
126 bool is_parseable_as<bool>(std::string
const& text) {
128 for (std::size_t i = 0; i < text.size(); ++i) {
129 lower.push_back(my_tolower(text[i]));
131 return lower ==
"true" || lower ==
"yes" ||
132 lower ==
"false" || lower ==
"no";
136 bool parse_as<bool>(std::string
const& text) {
138 for (std::size_t i = 0; i < text.size(); ++i) {
139 lower.push_back(my_tolower(text[i]));
141 return !(lower ==
"false" || lower ==
"no");
146 ParameterEntry value;
167 int infer_type()
const {
168 if (tag_type != -1) {
174 if (is_parseable_as<bool>(text)) {
177 if (is_parseable_as<int>(text)) {
180 if (is_parseable_as<long long>(text)) {
183 if (is_parseable_as<double>(text)) {
190 bool operator==(Scalar
const&, Scalar
const&) {
return false; }
191 std::ostream& operator<<(std::ostream& os, Scalar
const&) {
return os; }
193 void safe_set_entry(ParameterList& list, std::string
const& name_in, ParameterEntry
const& entry_in) {
195 "Parameter \"" << name_in <<
"\" already exists in list \"" << list.name() <<
"\"\n");
196 list.setEntry(name_in, entry_in);
199 namespace YAMLParameterList {
203 Reader():Teuchos::
Reader(Teuchos::YAML::ask_reader_tables()) {}
210 virtual void at_shift(any& result_any,
int token, std::string& text) {
213 case Teuchos::YAML::TOK_NEWLINE: {
214 std::string& result = make_any_ref<std::string>(result_any);
218 case Teuchos::YAML::TOK_SPACE:
219 case Teuchos::YAML::TOK_OTHER: {
220 result_any = text.at(0);
225 virtual void at_reduce(any& result_any,
int prod, std::vector<any>& rhs) {
228 case Teuchos::YAML::PROD_DOC:
229 case Teuchos::YAML::PROD_DOC2: {
230 std::size_t offset = prod == Teuchos::YAML::PROD_DOC2 ? 1 : 0;
232 swap(result_any, rhs.at(offset));
236 case Teuchos::YAML::PROD_TOP_BMAP: {
239 PLPair& pair = any_ref_cast<PLPair>(rhs.at(0));
240 any& pair_rhs_any = pair.value.getAny(
false);
241 result_any = pair_rhs_any;
244 case Teuchos::YAML::PROD_TOP_FIRST: {
245 if (rhs.at(0).type() ==
typeid(ParameterList)) {
246 swap(result_any, rhs.at(0));
250 case Teuchos::YAML::PROD_TOP_NEXT: {
251 if (rhs.at(1).type() ==
typeid(ParameterList)) {
253 "Can't specify multiple top-level ParameterLists in one YAML file!\n");
254 swap(result_any, rhs.at(1));
256 swap(result_any, rhs.at(0));
260 case Teuchos::YAML::PROD_BMAP_FIRST:
261 case Teuchos::YAML::PROD_FMAP_FIRST: {
263 map_first_item(result_any, rhs.at(0));
267 case Teuchos::YAML::PROD_BMAP_NEXT: {
268 map_next_item(result_any, rhs.at(0), rhs.at(1));
271 case Teuchos::YAML::PROD_FMAP_NEXT: {
272 map_next_item(result_any, rhs.at(0), rhs.at(3));
275 case Teuchos::YAML::PROD_BMAP_SCALAR:
276 case Teuchos::YAML::PROD_FMAP_SCALAR:
277 case Teuchos::YAML::PROD_FMAP_FMAP:
278 case Teuchos::YAML::PROD_FMAP_FSEQ: {
279 int scalar_type = interpret_tag(rhs.at(3));
280 map_item(result_any, rhs.at(0), rhs.at(4), scalar_type);
283 case Teuchos::YAML::PROD_BMAP_BSCALAR: {
284 map_item(result_any, rhs.at(0), rhs.at(3), Scalar::STRING);
287 case Teuchos::YAML::PROD_BMAP_BVALUE: {
288 map_item(result_any, rhs.at(0), rhs.at(4));
291 case Teuchos::YAML::PROD_BVALUE_EMPTY: {
292 result_any = ParameterList();
295 case Teuchos::YAML::PROD_BVALUE_BMAP:
296 case Teuchos::YAML::PROD_BVALUE_BSEQ: {
297 swap(result_any, rhs.at(1));
300 case Teuchos::YAML::PROD_BMAP_FMAP: {
301 map_item(result_any, rhs.at(0), rhs.at(4));
304 case Teuchos::YAML::PROD_BMAP_FSEQ: {
306 rhs.at(4).type() ==
typeid(Array<Array<Scalar>>));
307 int scalar_type = interpret_tag(rhs.at(3));
308 map_item(result_any, rhs.at(0), rhs.at(4), scalar_type);
311 case Teuchos::YAML::PROD_BSEQ_FIRST: {
312 seq_first_item(result_any, rhs.at(0));
315 case Teuchos::YAML::PROD_BSEQ_NEXT: {
316 seq_next_item(result_any, rhs.at(0), rhs.at(1));
319 case Teuchos::YAML::PROD_BSEQ_SCALAR: {
320 swap(result_any, rhs.at(3));
321 Scalar& scalar = any_ref_cast<Scalar>(result_any);
322 scalar.tag_type = interpret_tag(rhs.at(2));
325 case Teuchos::YAML::PROD_BSEQ_BSCALAR: {
326 swap(result_any, rhs.at(2));
329 case Teuchos::YAML::PROD_BSEQ_BMAP:
330 case Teuchos::YAML::PROD_BSEQ_BMAP_TRAIL:
331 case Teuchos::YAML::PROD_BSEQ_FMAP: {
332 throw ParserFail(
"Can't interpret a map inside a sequence as a Teuchos Parameter");
334 case Teuchos::YAML::PROD_BSEQ_BSEQ: {
335 swap(result_any, rhs.at(3));
338 case Teuchos::YAML::PROD_BSEQ_BSEQ_TRAIL: {
339 swap(result_any, rhs.at(4));
342 case Teuchos::YAML::PROD_BSEQ_FSEQ: {
343 swap(result_any, rhs.at(3));
346 case Teuchos::YAML::PROD_FMAP: {
347 swap(result_any, rhs.at(2));
350 case Teuchos::YAML::PROD_FMAP_EMPTY: {
351 result_any = ParameterList();
354 case Teuchos::YAML::PROD_FSEQ: {
355 swap(result_any, rhs.at(2));
357 result_any.type() ==
typeid(Array<Array<Scalar>>));
360 case Teuchos::YAML::PROD_FSEQ_EMPTY: {
361 result_any = Array<Scalar>();
364 case Teuchos::YAML::PROD_FSEQ_FIRST: {
365 seq_first_item(result_any, rhs.at(0));
368 case Teuchos::YAML::PROD_FSEQ_NEXT: {
369 seq_next_item(result_any, rhs.at(0), rhs.at(3));
372 case Teuchos::YAML::PROD_FSEQ_SCALAR: {
373 swap(result_any, rhs.at(1));
374 Scalar& scalar = any_ref_cast<Scalar>(result_any);
375 scalar.tag_type = interpret_tag(rhs.at(0));
378 case Teuchos::YAML::PROD_FSEQ_FSEQ:
379 case Teuchos::YAML::PROD_FSEQ_FMAP: {
380 swap(result_any, rhs.at(1));
383 case Teuchos::YAML::PROD_SCALAR_QUOTED:
384 case Teuchos::YAML::PROD_MAP_SCALAR_QUOTED: {
385 swap(result_any, rhs.at(0));
388 case Teuchos::YAML::PROD_SCALAR_RAW:
389 case Teuchos::YAML::PROD_MAP_SCALAR_RAW: {
390 Scalar& scalar = make_any_ref<Scalar>(result_any);
392 scalar.text = any_ref_cast<std::string>(rhs.at(0));
393 scalar.text += any_ref_cast<std::string>(rhs.at(1));
394 if (prod == Teuchos::YAML::PROD_MAP_SCALAR_RAW) {
395 scalar.text += any_ref_cast<std::string>(rhs.at(2));
397 scalar.text = remove_trailing_whitespace(scalar.text);
398 scalar.source = Scalar::RAW;
399 scalar.tag_type = -1;
402 case Teuchos::YAML::PROD_SCALAR_HEAD_OTHER:
403 case Teuchos::YAML::PROD_SCALAR_HEAD_DOT:
404 case Teuchos::YAML::PROD_SCALAR_HEAD_DASH:
405 case Teuchos::YAML::PROD_SCALAR_HEAD_DOT_DOT: {
407 if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_OTHER) offset = 0;
408 else if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DOT_DOT) offset = 2;
410 char second = any_cast<
char>(rhs.at(offset));
411 std::string& result = make_any_ref<std::string>(result_any);
412 if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DOT) result +=
'.';
413 else if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DASH) result +=
'-';
414 else if (prod == Teuchos::YAML::PROD_SCALAR_HEAD_DOT_DOT) result +=
"..";
418 case Teuchos::YAML::PROD_SCALAR_DQUOTED:
419 case Teuchos::YAML::PROD_SCALAR_SQUOTED: {
420 std::string& first = any_ref_cast<std::string>(rhs.at(1));
421 std::string& rest = any_ref_cast<std::string>(rhs.at(2));
422 Scalar& scalar = make_any_ref<Scalar>(result_any);
423 scalar.text += first;
425 if (prod == Teuchos::YAML::PROD_SCALAR_DQUOTED) {
426 scalar.source = Scalar::DQUOTED;
427 }
else if (prod == Teuchos::YAML::PROD_SCALAR_SQUOTED) {
428 scalar.source = Scalar::SQUOTED;
430 scalar.tag_type = -1;
433 case Teuchos::YAML::PROD_MAP_SCALAR_ESCAPED_EMPTY: {
434 result_any = std::string();
437 case Teuchos::YAML::PROD_MAP_SCALAR_ESCAPED_NEXT: {
438 swap(result_any, rhs.at(0));
439 std::string& str = any_ref_cast<std::string>(result_any);
441 str += any_ref_cast<std::string>(rhs.at(2));
444 case Teuchos::YAML::PROD_TAG: {
445 swap(result_any, rhs.at(2));
448 case Teuchos::YAML::PROD_BSCALAR: {
449 std::size_t parent_indent_level =
450 this->symbol_indentation_stack.at(
451 this->symbol_indentation_stack.size() - 5);
452 std::string& header = any_ref_cast<std::string>(rhs.at(0));
453 std::string& leading_empties_or_comments =
454 any_ref_cast<std::string>(rhs.at(2));
455 std::string& rest = any_ref_cast<std::string>(rhs.at(4));
456 std::string& content = make_any_ref<std::string>(result_any);
460 header, leading_empties_or_comments, rest,
464 case Teuchos::YAML::PROD_BSCALAR_FIRST: {
465 swap(result_any, rhs.at(0));
469 case Teuchos::YAML::PROD_BSCALAR_NEXT:
470 case Teuchos::YAML::PROD_BSCALAR_LINE:
471 case Teuchos::YAML::PROD_DESCAPE_NEXT:
472 case Teuchos::YAML::PROD_SESCAPE_NEXT: {
473 swap(result_any, rhs.at(0));
474 std::string& str = any_ref_cast<std::string>(result_any);
475 str += any_ref_cast<std::string>(rhs.at(1));
478 case Teuchos::YAML::PROD_BSCALAR_INDENT: {
479 swap(result_any, rhs.at(1));
482 case Teuchos::YAML::PROD_BSCALAR_HEADER_LITERAL:
483 case Teuchos::YAML::PROD_BSCALAR_HEADER_FOLDED: {
484 std::string& result = make_any_ref<std::string>(result_any);
485 if (prod == Teuchos::YAML::PROD_BSCALAR_HEADER_LITERAL) {
490 std::string& rest = any_ref_cast<std::string>(rhs.at(1));
494 case Teuchos::YAML::PROD_DESCAPE: {
495 std::string& str = make_any_ref<std::string>(result_any);
496 std::string& rest = any_ref_cast<std::string>(rhs.at(2));
497 str += any_cast<
char>(rhs.at(1));
501 case Teuchos::YAML::PROD_SESCAPE: {
502 std::string& str = make_any_ref<std::string>(result_any);
503 std::string& rest = any_ref_cast<std::string>(rhs.at(2));
508 case Teuchos::YAML::PROD_OTHER_FIRST:
509 case Teuchos::YAML::PROD_SPACE_PLUS_FIRST: {
510 std::string& str = make_any_ref<std::string>(result_any);
511 str.push_back(any_cast<char>(rhs.at(0)));
514 case Teuchos::YAML::PROD_SCALAR_TAIL_SPACE:
515 case Teuchos::YAML::PROD_SCALAR_TAIL_OTHER:
516 case Teuchos::YAML::PROD_DESCAPED_DQUOTED:
517 case Teuchos::YAML::PROD_DQUOTED_COMMON:
518 case Teuchos::YAML::PROD_SQUOTED_COMMON:
519 case Teuchos::YAML::PROD_ANY_COMMON:
520 case Teuchos::YAML::PROD_COMMON_SPACE:
521 case Teuchos::YAML::PROD_COMMON_OTHER:
522 case Teuchos::YAML::PROD_BSCALAR_HEAD_OTHER: {
523 swap(result_any, rhs.at(0));
527 case Teuchos::YAML::PROD_DQUOTED_NEXT:
528 case Teuchos::YAML::PROD_SQUOTED_NEXT:
529 case Teuchos::YAML::PROD_ANY_NEXT:
530 case Teuchos::YAML::PROD_SCALAR_TAIL_NEXT:
531 case Teuchos::YAML::PROD_SPACE_STAR_NEXT:
532 case Teuchos::YAML::PROD_SPACE_PLUS_NEXT:
533 case Teuchos::YAML::PROD_BSCALAR_HEAD_NEXT: {
535 "leading characters in " << prod <<
": any was empty\n");
536 swap(result_any, rhs.at(0));
537 std::string& str = any_ref_cast<std::string>(result_any);
538 str += any_cast<
char>(rhs.at(1));
541 case Teuchos::YAML::PROD_DQUOTED_EMPTY:
542 case Teuchos::YAML::PROD_SQUOTED_EMPTY:
543 case Teuchos::YAML::PROD_ANY_EMPTY:
544 case Teuchos::YAML::PROD_DESCAPE_EMPTY:
545 case Teuchos::YAML::PROD_SESCAPE_EMPTY:
546 case Teuchos::YAML::PROD_SCALAR_TAIL_EMPTY:
547 case Teuchos::YAML::PROD_SPACE_STAR_EMPTY:
548 case Teuchos::YAML::PROD_BSCALAR_HEAD_EMPTY: {
549 result_any = std::string();
552 case Teuchos::YAML::PROD_DESCAPED_DQUOT:
553 case Teuchos::YAML::PROD_SQUOTED_DQUOT:
554 case Teuchos::YAML::PROD_ANY_DQUOT: {
558 case Teuchos::YAML::PROD_DESCAPED_SLASH:
559 case Teuchos::YAML::PROD_SQUOTED_SLASH:
560 case Teuchos::YAML::PROD_ANY_SLASH: {
564 case Teuchos::YAML::PROD_SCALAR_TAIL_SQUOT:
565 case Teuchos::YAML::PROD_DQUOTED_SQUOT:
566 case Teuchos::YAML::PROD_ANY_SQUOT: {
570 case Teuchos::YAML::PROD_COMMON_COLON: {
574 case Teuchos::YAML::PROD_SCALAR_TAIL_DOT:
575 case Teuchos::YAML::PROD_COMMON_DOT: {
579 case Teuchos::YAML::PROD_SCALAR_TAIL_DASH:
580 case Teuchos::YAML::PROD_COMMON_DASH:
581 case Teuchos::YAML::PROD_BSCALAR_HEAD_DASH: {
585 case Teuchos::YAML::PROD_COMMON_PIPE: {
589 case Teuchos::YAML::PROD_COMMON_LSQUARE: {
593 case Teuchos::YAML::PROD_COMMON_RSQUARE: {
597 case Teuchos::YAML::PROD_COMMON_LCURLY: {
601 case Teuchos::YAML::PROD_COMMON_RCURLY: {
605 case Teuchos::YAML::PROD_COMMON_RANGLE: {
609 case Teuchos::YAML::PROD_COMMON_COMMA: {
613 case Teuchos::YAML::PROD_COMMON_PERCENT: {
617 case Teuchos::YAML::PROD_COMMON_EXCL: {
623 void map_first_item(any& result_any, any& first_item) {
624 ParameterList& list = make_any_ref<ParameterList>(result_any);
626 PLPair& pair = any_ref_cast<PLPair>(first_item);
627 safe_set_entry(list, pair.key, pair.value);
629 void map_next_item(any& result_any, any& items, any& next_item) {
631 swap(result_any, items);
632 ParameterList& list = any_ref_cast<ParameterList>(result_any);
633 PLPair& pair = any_ref_cast<PLPair>(next_item);
634 safe_set_entry(list, pair.key, pair.value);
636 void map_item(any& result_any, any& key_any, any& value_any,
int scalar_type = -1) {
638 PLPair& result = make_any_ref<PLPair>(result_any);
640 std::string& key = any_ref_cast<Scalar>(key_any).text;
641 swap(result.key, key);
643 resolve_map_value(value_any, scalar_type);
644 if (value_any.type() ==
typeid(bool)) {
645 bool value = any_cast<
bool>(value_any);
646 result.value = ParameterEntry(value);
647 }
else if (value_any.type() ==
typeid(int)) {
648 int value = any_cast<
int>(value_any);
649 result.value = ParameterEntry(value);
650 }
else if (value_any.type() ==
typeid(
long long)) {
651 long long value = any_cast<
long long>(value_any);
652 result.value = ParameterEntry(value);
653 }
else if (value_any.type() ==
typeid(double)) {
654 double value = any_cast<
double>(value_any);
655 result.value = ParameterEntry(value);
656 }
else if (value_any.type() ==
typeid(std::string)) {
657 std::string& value = any_ref_cast<std::string >(value_any);
658 result.value = ParameterEntry(value);
659 }
else if (value_any.type() ==
typeid(Array<int>)) {
660 Array<int>& value = any_ref_cast<Array<int> >(value_any);
661 result.value = ParameterEntry(value);
662 }
else if (value_any.type() ==
typeid(Array<long long>)) {
663 Array<long long>& value = any_ref_cast<Array<long long> >(value_any);
664 result.value = ParameterEntry(value);
665 }
else if (value_any.type() ==
typeid(Array<double>)) {
666 Array<double>& value = any_ref_cast<Array<double> >(value_any);
667 result.value = ParameterEntry(value);
668 }
else if (value_any.type() ==
typeid(Array<std::string>)) {
669 Array<std::string>& value = any_ref_cast<Array<std::string> >(value_any);
670 result.value = ParameterEntry(value);
671 }
else if (value_any.type() ==
typeid(TwoDArray<int>)) {
672 TwoDArray<int>& value = any_ref_cast<TwoDArray<int> >(value_any);
673 result.value = ParameterEntry(value);
674 }
else if (value_any.type() ==
typeid(TwoDArray<long long>)) {
675 TwoDArray<long long>& value = any_ref_cast<TwoDArray<long long> >(value_any);
676 result.value = ParameterEntry(value);
677 }
else if (value_any.type() ==
typeid(TwoDArray<double>)) {
678 TwoDArray<double>& value = any_ref_cast<TwoDArray<double> >(value_any);
679 result.value = ParameterEntry(value);
680 }
else if (value_any.type() ==
typeid(TwoDArray<std::string>)) {
681 TwoDArray<std::string>& value = any_ref_cast<TwoDArray<std::string> >(value_any);
682 result.value = ParameterEntry(value);
683 }
else if (value_any.type() ==
typeid(ParameterList)) {
684 ParameterList& value = any_ref_cast<ParameterList>(value_any);
685 ParameterList& result_pl = result.value.setList();
686 swap(result_pl, value);
687 result_pl.setName(result.key);
689 std::string msg =
"unexpected YAML map value type ";
690 msg += value_any.type().name();
691 msg +=
" for key \"";
694 throw ParserFail(msg);
697 void resolve_map_value(any& value_any,
int scalar_type = -1)
const {
698 if (value_any.type() ==
typeid(Scalar)) {
699 Scalar& scalar_value = any_ref_cast<Scalar>(value_any);
700 if (scalar_type == -1) {
701 scalar_type = scalar_value.infer_type();
703 if (scalar_type == Scalar::BOOL) {
704 value_any = parse_as<bool>(scalar_value.text);
705 }
else if (scalar_type == Scalar::INT) {
706 value_any = parse_as<int>(scalar_value.text);
707 }
else if (scalar_type == Scalar::LONG_LONG) {
708 value_any = parse_as<long long>(scalar_value.text);
709 }
else if (scalar_type == Scalar::DOUBLE) {
710 value_any = parse_as<double>(scalar_value.text);
712 value_any = scalar_value.text;
714 }
else if (value_any.type() ==
typeid(Array<Scalar>)) {
715 Array<Scalar>& scalars = any_ref_cast<Array<Scalar> >(value_any);
716 if (scalar_type == -1) {
717 if (scalars.size() == 0) {
718 throw ParserFail(
"implicitly typed arrays can't be empty\n"
719 "(need to determine their element type)\n");
723 scalar_type = Scalar::INT;
724 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
725 scalar_type = std::min(scalar_type, scalars[i].infer_type());
728 if (scalar_type == Scalar::INT) {
729 Array<int> result(scalars.size());
730 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
731 result[i] = parse_as<int>(scalars[i].text);
734 }
else if (scalar_type == Scalar::LONG_LONG) {
735 Array<long long> result(scalars.size());
736 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
737 result[i] = parse_as<long long>(scalars[i].text);
740 }
else if (scalar_type == Scalar::DOUBLE) {
741 Array<double> result(scalars.size());
742 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
743 result[i] = parse_as<double>(scalars[i].text);
746 }
else if (scalar_type == Scalar::STRING) {
747 Array<std::string> result(scalars.size());
748 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
749 result[i] = scalars[i].text;
753 }
else if (value_any.type() ==
typeid(Array<Array<Scalar>>)) {
754 Array<Array<Scalar>>& scalars = any_ref_cast<Array<Array<Scalar>> >(value_any);
755 if (scalar_type == -1) {
756 if (scalars.size() == 0) {
757 throw ParserFail(
"implicitly typed 2D arrays can't be empty\n"
758 "(need to determine their element type)\n");
762 scalar_type = Scalar::INT;
763 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
764 if (scalars[0].size() == 0) {
765 throw ParserFail(
"implicitly typed 2D arrays can't have empty rows\n"
766 "(need to determine their element type)\n");
768 if (scalars[i].size() != scalars[0].size()) {
769 throw ParserFail(
"2D array: sub-arrays are different sizes");
771 for (Teuchos_Ordinal j = 0; j < scalars[i].size(); ++j) {
772 int item_type = scalars[i][j].infer_type();
773 scalar_type = std::min(scalar_type, item_type);
777 if (scalar_type == Scalar::INT) {
778 TwoDArray<int> result(scalars.size(), scalars[0].size());
779 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
780 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
781 result(i, j) = parse_as<int>(scalars[i][j].text);
785 }
else if (scalar_type == Scalar::LONG_LONG) {
786 TwoDArray<long long> result(scalars.size(), scalars[0].size());
787 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
788 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
789 result(i, j) = parse_as<long long>(scalars[i][j].text);
793 }
else if (scalar_type == Scalar::DOUBLE) {
794 TwoDArray<double> result(scalars.size(), scalars[0].size());
795 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
796 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
797 result(i, j) = parse_as<double>(scalars[i][j].text);
801 }
else if (scalar_type == Scalar::STRING) {
802 TwoDArray<std::string> result(scalars.size(), scalars[0].size());
803 for (Teuchos_Ordinal i = 0; i < scalars.size(); ++i) {
804 for (Teuchos_Ordinal j = 0; j < scalars[0].size(); ++j) {
805 result(i, j) = scalars[i][j].text;
812 int interpret_tag(any& tag_any) {
813 if (tag_any.type() !=
typeid(std::string))
return -1;
814 std::string& text = any_ref_cast<std::string>(tag_any);
815 if (text.find(
"bool") != std::string::npos)
return Scalar::BOOL;
816 else if (text.find(
"int") != std::string::npos)
return Scalar::INT;
817 else if (text.find(
"double") != std::string::npos)
return Scalar::DOUBLE;
818 else if (text.find(
"string") != std::string::npos)
return Scalar::STRING;
820 std::string msg =
"Unable to parse type tag \"";
823 throw ParserFail(msg);
826 void seq_first_item(any& result_any, any& first_any) {
828 if (first_any.type() ==
typeid(Scalar)) {
829 Array<Scalar>& a = make_any_ref<Array<Scalar> >(result_any);
830 Scalar& v = any_ref_cast<Scalar>(first_any);
831 a.push_back(Scalar());
833 }
else if (first_any.type() ==
typeid(Array<Scalar>)) {
834 Array<Array<Scalar>>& a = make_any_ref<Array<Array<Scalar>> >(result_any);
835 Array<Scalar>& v = any_ref_cast<Array<Scalar> >(first_any);
836 a.push_back(Array<Scalar>());
840 "bug in YAMLParameterList::Reader: unexpected type for first sequence item");
843 void seq_next_item(any& result_any, any& items, any& next_item) {
845 swap(result_any, items);
846 if (result_any.type() ==
typeid(Array<Scalar>)) {
847 Array<Scalar>& a = any_ref_cast<Array<Scalar> >(result_any);
848 Scalar& val = any_ref_cast<Scalar>(next_item);
849 a.push_back(Scalar());
851 }
else if (result_any.type() ==
typeid(Array<Array<Scalar>>)) {
852 Array<Array<Scalar>>& a = any_ref_cast<Array<Array<Scalar>> >(result_any);
853 Array<Scalar>& v = any_ref_cast<Array<Scalar> >(next_item);
854 a.push_back(Array<Scalar>());
858 "bug in YAMLParameterList::Reader: unexpected type for next sequence item");
862 void handle_block_scalar(
863 std::size_t parent_indent_level,
864 std::string
const& header,
865 std::string
const& leading_empties_or_comments,
866 std::string
const& rest,
867 std::string& content,
868 std::string& comment) {
871 char chomping_indicator;
872 std::size_t indentation_indicator = 0;
874 std::stringstream ss(header.substr(1,std::string::npos));
875 if (header.size() > 1 && my_isdigit(header[1])) {
876 ss >> indentation_indicator;
878 indentation_indicator += parent_indent_level;
880 if (!(ss >> chomping_indicator)) chomping_indicator =
'\0';
883 std::size_t first_newline = leading_empties_or_comments.find_first_of(
"\r\n");
885 if (first_newline > 0 && leading_empties_or_comments[first_newline - 1] ==
'\r') {
890 std::size_t keep_beg = first_newline + 1 - newline.size();
891 if (leading_empties_or_comments[0] ==
'#') {
892 comment = leading_empties_or_comments.substr(1, keep_beg);
895 std::size_t content_beg = leading_empties_or_comments.find_first_not_of(
"\r\n ");
896 if (content_beg == std::string::npos) content_beg = leading_empties_or_comments.size();
897 std::size_t newline_before_content = leading_empties_or_comments.rfind(
"\n", content_beg);
898 std::size_t num_indent_spaces = (content_beg - newline_before_content) - 1;
901 if (indentation_indicator > 0) {
904 "Indentation indicator " << indentation_indicator <<
" > leading spaces " << num_indent_spaces);
905 num_indent_spaces = indentation_indicator;
908 content = leading_empties_or_comments.substr(keep_beg, std::string::npos);
917 auto last_newline = content.find_last_of(
"\n", content.size() - 2);
918 if (last_newline == std::string::npos)
break;
919 std::size_t num_spaces = 0;
920 for (
auto ispace = last_newline + 1;
921 ispace < content.size() && content[ispace] ==
' ';
925 if (num_spaces >= num_indent_spaces)
break;
926 content.erase(content.begin() + last_newline + 1, content.end());
929 std::size_t unindent_pos = 0;
931 std::size_t next_newline = content.find_first_of(
"\n", unindent_pos);
932 if (next_newline == std::string::npos)
break;
933 std::size_t start_cut = next_newline + 1;
935 if (style ==
'>') start_cut -= newline.size();
936 std::size_t end_cut = next_newline + 1;
939 while (end_cut < content.size() && content[end_cut] ==
' ') {
943 end_cut = std::min(next_newline + 1 + num_indent_spaces, end_cut);
945 content = content.substr(0, start_cut) +
946 content.substr(end_cut, std::string::npos);
947 unindent_pos = start_cut;
949 if (chomping_indicator !=
'+') {
950 content = remove_trailing_whitespace_and_newlines(content);
951 if (chomping_indicator !=
'-') content += newline;
955 content = content.substr(newline.size(), std::string::npos);
964 void updateParametersFromYamlFile(
const std::string& yamlFileName,
969 if (paramList->
name() ==
"ANONYMOUS") {
976 void updateParametersFromYamlCString(
const char*
const data,
983 if (paramList->
name() ==
"ANONYMOUS") {
994 void updateParametersFromYamlString(
const std::string& yamlData,
997 const std::string& name)
1002 if (paramList->
name() ==
"ANONYMOUS") {
1015 return YAMLParameterList::parseYamlFile(yamlFileName);
1020 std::stringstream ss(yamlStr);
1021 return YAMLParameterList::parseYamlStream(ss);
1024 void writeParameterListToYamlOStream(
1026 std::ostream &yamlOut
1029 YAMLParameterList::writeYamlStream(yamlOut, paramList);
1032 void writeParameterListToYamlFile(
1034 const std::string &yamlFileName
1037 YAMLParameterList::writeYamlFile(yamlFileName, paramList);
1040 std::string convertXmlToYaml(
const std::string& xmlFileName)
1045 std::string yamlFileName;
1046 if(xmlFileName.find(
".xml") == std::string::npos)
1048 yamlFileName = xmlFileName +
".yaml";
1052 yamlFileName = xmlFileName.substr(0, xmlFileName.length() - 4) +
".yaml";
1054 YAMLParameterList::writeYamlFile(yamlFileName, *toConvert);
1055 return yamlFileName;
1058 void convertXmlToYaml(
const std::string& xmlFileName,
const std::string& yamlFileName)
1061 YAMLParameterList::writeYamlFile(yamlFileName, *toConvert);
1064 void convertXmlToYaml(std::istream& xmlStream, std::ostream& yamlStream)
1067 std::istreambuf_iterator<char> begin(xmlStream);
1068 std::istreambuf_iterator<char> end;
1069 std::string xmlString(begin, end);
1071 YAMLParameterList::writeYamlStream(yamlStream, *toConvert);
1074 namespace YAMLParameterList
1079 Teuchos::YAMLParameterList::Reader reader;
1081 reader.read_string(result, text, name);
1082 ParameterList& pl = any_ref_cast<ParameterList>(result);
1088 Teuchos::YAMLParameterList::Reader reader;
1090 reader.read_file(result, yamlFile);
1091 ParameterList& pl = any_ref_cast<ParameterList>(result);
1097 Teuchos::YAMLParameterList::Reader reader;
1099 reader.read_stream(result, yaml,
"parseYamlStream");
1100 ParameterList& pl = any_ref_cast<ParameterList>(result);
1107 std::ios_base::fmtflags flags = yaml.flags();
1109 std::ostringstream testStream;
1110 testStream.flags(flags);
1112 testStream << testVal;
1113 bool popFlags =
false;
1114 if(testStream.str() ==
"1")
1120 std::cout <<
"Warning: yaml stream format flags would confuse double with integer value with int.\n";
1121 std::cout <<
"Setting std::ios::showpoint on the stream to fix this (will restore flags when done)\n";
1122 std::ios_base::fmtflags flagsCopy = flags;
1123 flagsCopy |= std::ios::showpoint;
1126 yaml <<
"%YAML 1.1\n---\n";
1127 yaml << pl.
name() <<
':';
1134 writeParameterList(pl, yaml, 2);
1146 std::ofstream yaml(yamlFile.c_str());
1153 yaml << std::scientific << std::setprecision(17);
1154 writeYamlStream(yaml, pl);
1166 for(PLIter it = pl.
begin(); it != pl.
end(); it++)
1168 writeParameter(pl.
name(it), pl.
entry(it), yaml, indentLevel);
1173 template <
typename T>
1175 static void write(T
const& x, std::ostream& stream) {
1181 struct YamlWrite<double> {
1182 static void write(
double const& x, std::ostream& stream) {
1183 generalWriteDouble(x, stream);
1188 struct YamlWrite<std::string> {
1189 static void write(std::string
const& x, std::ostream& stream) {
1190 generalWriteString(x, stream);
1194 template <
typename T>
1201 if (i) stream <<
", ";
1205 if (j) stream <<
", ";
1206 YamlWrite<T>::write(arr(i, j), stream);
1213 void writeParameter(
const std::string& paramName,
const Teuchos::ParameterEntry& entry, std::ostream& yaml,
int indentLevel)
1215 for(
int i = 0; i < indentLevel; i++)
1219 generalWriteString(paramName, yaml);
1223 writeParameterList(Teuchos::getValue<Teuchos::ParameterList>(entry), yaml, indentLevel + 2);
1232 for(
int i = 0; i < arr.
size(); i++)
1235 if(i != arr.size() - 1)
1242 for(
int i = 0; i < arr.
size(); i++)
1245 if(i != arr.size() - 1)
1252 for(
int i = 0; i < arr.
size(); i++)
1254 generalWriteDouble(arr[i], yaml);
1255 if(i != arr.
size() - 1)
1262 for(
int i = 0; i < arr.
size(); i++)
1264 generalWriteString(arr[i], yaml);
1265 if(i != arr.
size() - 1)
1275 writeYamlTwoDArray<int>(
1276 Teuchos::getValue<Teuchos::TwoDArray<int> >(entry), yaml);
1280 writeYamlTwoDArray<long long>(
1281 Teuchos::getValue<Teuchos::TwoDArray<long long> >(entry), yaml);
1285 writeYamlTwoDArray<double>(
1286 Teuchos::getValue<Teuchos::TwoDArray<double> >(entry), yaml);
1290 writeYamlTwoDArray<std::string>(
1291 Teuchos::getValue<Teuchos::TwoDArray<std::string> >(entry), yaml);
1294 else if(entry.
isType<
int>())
1296 yaml << Teuchos::getValue<int>(entry);
1298 else if(entry.
isType<
long long>())
1300 yaml << Teuchos::getValue<long long>(entry);
1302 else if(entry.
isType<
double>())
1304 generalWriteDouble(Teuchos::getValue<double>(entry), yaml);
1306 else if(entry.
isType<std::string>())
1308 std::string& str = Teuchos::getValue<std::string>(entry);
1309 if(strchr(str.c_str(),
'\n'))
1315 std::size_t first_non_newline_pos = str.find_first_not_of(
"\r\n");
1316 if (first_non_newline_pos != std::string::npos &&
1317 str[first_non_newline_pos] ==
' ') {
1320 if (str[str.size() - 1] !=
'\n') yaml <<
"-";
1326 size_t next = str.find(
'\n', index);
1327 for(
int i = 0; i < indentLevel + 2; i++)
1331 if(next == std::string::npos)
1333 yaml << str.substr(index, std::string::npos);
1338 yaml << str.substr(index, next - index) <<
'\n';
1345 generalWriteString(str, yaml);
1348 else if(entry.
isType<
bool>())
1350 yaml << (Teuchos::getValue<bool>(entry) ?
"true" :
"false");
1355 void generalWriteString(
const std::string& str, std::ostream& yaml)
1358 if(stringNeedsQuotes(str))
1361 for (std::size_t i = 0; i < str.size(); ++i) {
1362 if (str[i] ==
'\'') yaml <<
"''";
1363 else yaml << str[i];
1373 void generalWriteDouble(
double d, std::ostream& yaml)
1378 static bool containsSpecialCharacters(std::string
const& s) {
1379 char const*
const control_chars =
":'{}[],&*#?|<>=!%@\\";
1380 return s.find_first_of(control_chars) != std::string::npos;
1383 bool stringNeedsQuotes(
const std::string& s)
1386 containsSpecialCharacters(s) ||
1387 is_parseable_as<bool>(s) ||
1388 is_parseable_as<int>(s) ||
1389 is_parseable_as<long long>(s) ||
1390 is_parseable_as<double>(s);
A thin wrapper around the Teuchos Array class that allows for 2 dimensional arrays.
const std::string & name() const
The name of this ParameterList.
Reader(ReaderTablesPtr tables_in)
Constructor: accepts an RCP to ReaderTables.
ConstIterator end() const
An iterator pointing beyond the last entry.
Functions to convert between ParameterList and YAML.
This object is held as the "value" in the Teuchos::ParameterList std::map.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
bool isArray() const
Test if the type of data being contained is a Teuchos::Array.
Tries to create LALR(1) parser tables for a given grammar.
bool isType() const
Test the type of the data being contained.
Ordinal numParams() const
Get the number of stored parameters.
A TeuchosParser Language for a subset of YAML.
Simple helper functions that make it easy to read and write XML to and from a parameterlist.
A thin wrapper around the Array class which causes it to be interpreted as a 2D Array.
The main class for users to read text using TeuchosParser.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
size_type getNumCols() const
returns the number of columns in the TwoDArray.
ConstIterator begin() const
An iterator pointing to the first entry.
bool isList() const
Return whether or not the value itself is a list.
A list of parameters of arbitrary type.
ParameterList & setParameters(const ParameterList &source)
const ParameterEntry & entry(ConstIterator i) const
Access to ParameterEntry (i.e., returns i->second)
size_type getNumRows() const
returns the number of rows in the TwoDArray.
ParameterList & setParametersNotAlreadySet(const ParameterList &source)
bool isTwoDArray() const
Test if the type of data being contained is a Teuchos::TwoDArray.
ParameterList & setName(const std::string &name)
Set the name of *this list.
#define TEUCHOS_ASSERT(assertion_test)
This macro is throws when an assert fails.
Simple helper functions that make it easy to read and write Yaml to and from a parameterlist.
Simple wrapper class for raw pointers to single objects where no persisting relationship exists...
Declares Teuchos::Reader.