parse.cc
Go to the documentation of this file.
1 // ======================================================================
2 //
3 // parse
4 //
5 // ======================================================================
6 
7 #include "fhiclcpp/parse.h"
8 
9 #ifdef __ICC
10 #pragma warning(push, disable : 780)
11 #endif
12 #pragma GCC diagnostic push
13 #pragma GCC diagnostic ignored "-Wshadow"
14 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
15 #pragma GCC diagnostic ignored "-Wunused-parameter"
16 #include "boost/spirit/include/phoenix_bind.hpp"
17 #include "boost/spirit/include/phoenix_operator.hpp"
18 #include "boost/spirit/include/qi.hpp"
19 #include "boost/spirit/include/qi_no_skip.hpp"
20 #include "boost/spirit/include/support_istream_iterator.hpp"
21 #ifdef __clang__
22 #pragma clang diagnostic ignored "-Wpedantic"
23 #else
24 #pragma GCC diagnostic ignored "-Wpedantic"
25 #endif
26 #include "boost/spirit/repository/home/qi/primitive/iter_pos.hpp"
27 #pragma GCC diagnostic pop
28 #ifdef __ICC
29 #pragma warning(pop)
30 #endif
31 
34 #include "cetlib/include.h"
35 #include "cetlib/includer.h"
37 #include "fhiclcpp/exception.h"
40 #include "fhiclcpp/parse_shims.h"
41 #include "fhiclcpp/tokens.h"
42 
43 #include <algorithm>
44 #include <any>
45 #include <string>
46 #include <vector>
47 
48 namespace ascii = ::boost::spirit::ascii;
49 namespace phx = ::boost::phoenix;
50 namespace qi = ::boost::spirit::qi;
51 
52 using ascii::char_;
53 using ascii::digit;
54 using ascii::graph;
55 using ascii::space;
56 
57 using phx::ref;
58 
59 using boost::spirit::repository::qi::iter_pos;
60 using qi::_val;
61 using qi::eol;
62 using qi::lexeme;
63 using namespace shims; // using qi::lit; /*moved to parse_shims.h*/
64 using qi::no_skip;
65 using qi::raw;
66 using qi::skip;
67 
68 using namespace fhicl;
74 
75 using fhicl::SEQUENCE;
76 using fhicl::TABLE;
77 using fhicl::TABLEID;
78 
79 // ----------------------------------------------------------------------
80 
81 namespace {
82 
83  void
84  check_element_protections(std::string const& name,
85  Protection const p,
86  extended_value& v)
87  {
88  using std::max;
89  if (v.protection == Protection::NONE) {
90  v.protection = p;
91  } else if (v.protection < p) {
93  << "Nested item " << name << " has protection "
94  << to_string(v.protection)
95  << ((!v.src_info.empty()) ?
96  (std::string(" on ") + v.pretty_src_info()) :
97  "")
98  << ", which is incompatible with an enclosing item's protection of "
99  << to_string(p) << "\n";
100  }
101 
102  if (v.tag == fhicl::SEQUENCE) {
103  std::size_t count = 0;
104  for (auto& subv : sequence_t(v)) {
105  check_element_protections(
106  name + '[' + std::to_string(count) + ']', max(p, v.protection), subv);
107  }
108  } else if (v.tag == fhicl::TABLE) {
109  for (auto& [key, value] : table_t(v)) {
110  std::string sname(name);
111  if (!sname.empty()) {
112  sname.append(".");
113  }
114  sname.append(key);
115  check_element_protections(sname, max(p, v.protection), value);
116  }
117  }
118  }
119 
120  void
121  check_protection(std::string const& name, extended_value& v)
122  {
123  if (v.is_a(SEQUENCE) || v.is_a(TABLE)) {
124  check_element_protections(name, v.protection, v);
125  }
126  }
127 
128  void
129  set_protection(std::string const& name,
130  binding_modifier const m,
131  extended_value& v)
132  {
133  if (m == binding_modifier::NONE) {
134  return;
135  }
136 
137  v.protection = static_cast<Protection>(m);
138  check_protection(name, v);
139  }
140 
142  canon_nil()
143  {
144  static std::string const canon_nil(9, '\0');
145  return canon_nil;
146  }
147 
149  canon_inf(std::string const& inf)
150  {
151  return inf[0] == 'i' ? ('+' + inf) : inf;
152  }
153 
155  canon_num(std::string const& num)
156  {
158  return cet::canonical_number(num, result) ?
159  result :
161  << "The string '" << num
162  << "' is not representable as a canonical number.";
163  }
164 
166  canon_str(std::string const& str)
167  {
169  return cet::canonical_string(str, result) ?
170  result :
172  << "The string " + str +
173  " is not representable as a canonical string.\n"
174  << "It is likely you have an unescaped (or incorrectly escaped) "
175  "character.";
176  }
177 
179  xvalue_vp(bool const b, value_tag const t, std::any const v)
180  {
181  return extended_value{b, t, v};
182  }
183 
184  using iter_t = cet::includer::const_iterator;
185 
186  complex_t
187  cplx(atom_t const& c1, atom_t const& c2)
188  {
189  return std::make_pair(c1, c2);
190  }
191 
192  void
193  map_insert(std::string const& name,
194  binding_modifier const m,
196  table_t& t)
197  {
198  set_protection(name, m, value);
199  auto const i = t.find(name);
200  if (i != t.end()) {
201  auto existing_protection = i->second.protection;
202  if (value.protection > existing_protection) {
204  << "Inserting name " << name << " would increase protection from "
205  << to_string(existing_protection) << " to "
206  << to_string(value.protection) << "\n(previous definition on "
207  << i->second.pretty_src_info() << ")\n";
208  }
209  switch (i->second.protection) {
210  case Protection::NONE:
211  break;
212  case Protection::PROTECT_IGNORE:
213  // Do not overwrite protected binding.
214  return;
215  case Protection::PROTECT_ERROR:
217  << '"' << name << "\" is protected on " << i->second.pretty_src_info()
218  << '\n';
219  }
220  }
221  t[name] = value;
222  }
223 
224  void
225  map_insert_loc(std::string const& name,
226  binding_modifier const m,
227  extended_value& value,
228  table_t& t,
229  iter_t const pos,
230  cet::includer const& s) try {
231  map_insert(name, m, value, t);
232  }
233  catch (fhicl::exception& e) {
234  throw fhicl::exception(fhicl::error::parse_error, "Error in assignment:", e)
235  << " at " << s.highlighted_whereis(pos) << '\n';
236  }
237 
238  void
239  seq_insert_value(extended_value xval, sequence_t& v)
240  {
241  xval.protection = Protection::NONE;
242  v.emplace_back(std::move(xval));
243  }
244 
245  void
246  map_erase(std::string const& name, table_t& t)
247  {
248  auto const i = t.find(name);
249  if (i == t.end())
250  return;
251 
252  switch (i->second.protection) {
253  case Protection::NONE:
254  t.erase(name);
255  case Protection::PROTECT_IGNORE:
256  return;
257  case Protection::PROTECT_ERROR:
259  << "Unable to erase " << name << " due to protection.\n";
260  }
261  }
262 
263  void
264  map_erase_loc(std::string const& name,
265  table_t& t,
266  iter_t const pos,
267  cet::includer const& s) try {
268  map_erase(name, t);
269  }
270  catch (fhicl::exception& e) {
271  throw fhicl::exception(
272  fhicl::error::parse_error, "Error in erase attempt:", e)
273  << " at " << s.highlighted_whereis(pos) << '\n';
274  }
275 
276  // ----------------------------------------------------------------------
277 
278  using FwdIter = std::string::const_iterator;
279 
280  template <typename Skip>
281  struct value_parser : qi::grammar<FwdIter, extended_value(), Skip> {
282  using atom_token = qi::rule<FwdIter, atom_t(), Skip>;
283  using complex_token = qi::rule<FwdIter, complex_t(), Skip>;
284  using sequence_token = qi::rule<FwdIter, sequence_t(), Skip>;
285  using table_token = qi::rule<FwdIter, table_t(), Skip>;
286  using value_token = qi::rule<FwdIter, extended_value(), Skip>;
287 
288  // default c'tor:
289  value_parser();
290 
291  // data member:
292  extended_value v{};
293 
294  // parser rules:
295  atom_token nil, boolean;
296  atom_token inf;
297  atom_token squoted, dquoted;
298  atom_token number, string, name, catchall;
299  atom_token id;
300  complex_token complex;
301  sequence_token sequence;
302  table_token table;
303  value_token value;
304 
305  }; // value_parser
306 
307  // ----------------------------------------------------------------------
308 
309  using Skip = qi::rule<iter_t>;
310  struct document_parser : qi::grammar<FwdIter, void(), Skip> {
311  using val_parser = value_parser<Skip>;
312  using atom_token = val_parser::atom_token;
313  using sequence_token = val_parser::sequence_token;
314  using table_token = val_parser::table_token;
315  using value_token = val_parser::value_token;
316  using nothing_token = qi::rule<FwdIter, void(), Skip>;
317 
318  explicit document_parser(cet::includer const& s);
319 
320  // data members:
321  bool in_prolog{false};
322  intermediate_table tbl{};
323  val_parser vp{};
324  cet::includer const& sref;
325 
326  // parser rules:
327  atom_token name, qualname, noskip_qualname, localref, dbref;
328  sequence_token sequence;
329  table_token table;
330  value_token value;
331  nothing_token prolog, document;
332 
333  private:
335  local_lookup(std::string const& name, iter_t const pos) try {
336  extended_value result = tbl.find(name);
337  result.set_prolog(in_prolog);
338  result.set_src_info(sref.src_whereis(pos));
339  result.reset_protection();
340  return result;
341  }
342  catch (fhicl::exception const& e) {
343  throw fhicl::exception(fhicl::error::parse_error, "Local lookup error", e)
344  << "at " << sref.highlighted_whereis(pos) << "\n";
345  }
346 
348  database_lookup(iter_t const pos)
349  {
351  "Database lookup error")
352  << "at " << sref.highlighted_whereis(pos)
353  << "\nFHiCL-cpp database lookup not yet available.\n";
354  }
355 
356  void
357  insert_table_in_table(std::string const& name, table_t& t, iter_t const pos)
358  {
359  extended_value const xval = local_lookup(name, pos);
360  if (!xval.is_a(fhicl::TABLE)) {
362  << "key \"" << name << "\" does not refer to a table at "
363  << sref.highlighted_whereis(pos) << "\n";
364  }
365  auto const& incoming = std::any_cast<table_t const&>(xval.value);
366  for (auto const& [name, value] : incoming) {
367  auto& element = t[name];
368  if (!element.is_a(fhicl::UNKNOWN)) {
369  // Already exists.
370  auto const incoming_protection = value.protection;
371  if (incoming_protection > element.protection) {
373  << "@table::" << name << ": inserting name " << name
374  << " would increase protection from "
375  << to_string(element.protection) << " to "
376  << to_string(incoming_protection) << "\n(previous definition on "
377  << element.pretty_src_info() << ")\n";
378  }
379  switch (element.protection) {
380  case Protection::NONE:
381  break;
382  case Protection::PROTECT_IGNORE:
383  continue;
384  case Protection::PROTECT_ERROR:
386  << "@table::" << name << ": inserting name " << name
387  << "would violate protection on existing item"
388  << "\n(previous definition on " << element.pretty_src_info()
389  << ")\n";
390  }
391  }
392  element = value;
393  element.set_prolog(in_prolog);
394  element.set_src_info(sref.src_whereis(pos));
395  }
396  }
397 
398  void
399  insert_table(std::string const& name, iter_t const pos)
400  {
401  extended_value const xval = local_lookup(name, pos);
402  if (!xval.is_a(fhicl::TABLE)) {
404  << "key \"" << name << "\" does not refer to a table at "
405  << sref.highlighted_whereis(pos) << "\n";
406  }
407  auto const& incoming = std::any_cast<table_t const&>(xval.value);
408  for (auto const& [name, value] : incoming) {
409  auto element = value;
410  element.set_prolog(in_prolog);
411  element.set_src_info(sref.src_whereis(pos));
412  tbl.insert(name, std::move(element));
413  }
414  }
415 
416  void
417  seq_insert_sequence(std::string const& name,
418  sequence_t& v,
419  iter_t const pos)
420  {
421  extended_value const xval = local_lookup(name, pos);
422  if (!xval.is_a(fhicl::SEQUENCE)) {
423  throw fhicl::exception(fhicl::error::type_mismatch, "@sequence::")
424  << "key \"" << name << "\" does not refer to a sequence at "
425  << sref.highlighted_whereis(pos) << "\n";
426  }
427  auto const& incoming = std::any_cast<sequence_t const&>(xval.value);
428  auto it = v.insert(v.end(), incoming.cbegin(), incoming.cend());
429  for (auto const e = v.end(); it != e; ++it) {
430  using std::to_string;
431  it->protection = Protection::NONE;
432  it->set_prolog(in_prolog);
433  it->set_src_info(sref.src_whereis(pos));
434  }
435  }
436 
438  xvalue_(value_tag const t, std::any const v, iter_t const pos)
439  {
440  return extended_value{in_prolog, t, v, sref.src_whereis(pos)};
441  }
442 
443  auto
444  xvalue_for(value_tag const t)
445  {
446  return phx::bind(&document_parser::xvalue_, this, t, qi::_2, qi::_1);
447  }
448 
449  void
450  tbl_erase(std::string const& name, iter_t const pos) try {
451  tbl.erase(name, in_prolog);
452  }
453  catch (fhicl::exception& e) {
454  throw fhicl::exception(
455  fhicl::error::parse_error, "Error in erase attempt:", e)
456  << " at " << sref.highlighted_whereis(pos) << '\n';
457  }
458 
459  void
460  tbl_insert(std::string const& name,
461  binding_modifier const m,
462  extended_value& value,
463  iter_t const pos) try {
464  set_protection(name, m, value);
465  tbl.insert(name, value);
466  }
467  catch (fhicl::exception& e) {
468  throw fhicl::exception(
469  fhicl::error::parse_error, "Error in assignment:", e)
470  << " at " << sref.highlighted_whereis(pos) << '\n';
471  }
472 
473  void
474  set_in_prolog(bool const value)
475  {
476  in_prolog = value;
477  }
478 
479  }; // document_parser
480 
481  // ----------------------------------------------------------------------
482 
483  template <class Skip>
484  value_parser<Skip>::value_parser() : value_parser::base_type{value}
485  {
486  nil = lexeme[(qi::string("@nil") >>
487  !(graph - char_(",]}")))[_val = phx::bind(canon_nil)]];
488  boolean = lexeme[(qi::string("true") | qi::string("false")) >>
489  !(graph - char_(",]}"))];
490  inf = lexeme[-(qi::string("+") | qi::string("-")) >>
491  qi::string("infinity") >> !(graph - char_("),]}"))];
492  squoted = lexeme[char_('\'') >> *(char_ - char_('\'')) >> char_('\'') >>
493  !(graph - char_(",]}"))];
494  dquoted =
495  lexeme[raw[char_('\"') >> *(qi::string("\\\"") | (char_ - char_('\"'))) >>
496  char_('\"') >> !(graph - char_(",]}"))]];
497  number =
498  (fhicl::uint[_val = phx::bind(canon_num, qi::_1)] |
499  inf[_val = phx::bind(canon_inf, qi::_1)] | fhicl::real[_val = qi::_1] |
500  fhicl::hex[_val = qi::_1] | fhicl::bin[_val = qi::_1]);
501  string = (fhicl::ass | fhicl::dss | squoted |
502  dquoted)[_val = phx::bind(canon_str, ref(qi::_1))];
503  name = fhicl::ass[_val = qi::_1];
504  complex = (lit('(') > number > lit(',') > number >
505  lit(')'))[_val = phx::bind(cplx, qi::_1, qi::_2)];
506  sequence = lit('[') > -(value % ',') > lit(']');
507  table =
508  lit('{') >
509  *((name >> fhicl::binding >>
510  value)[phx::bind(map_insert, ref(qi::_1), qi::_2, ref(qi::_3), _val)] |
511  (name >>
512  (lit(':') > lit("@erase")))[phx::bind(map_erase, ref(qi::_1), _val)]) >
513  lit('}');
514  id = lit("@id::") > no_skip[fhicl::dbid][_val = qi::_1];
515  catchall = shims::catchall[_val = phx::bind(canon_str, ref(qi::_1))];
516  value = (nil[_val = phx::bind(xvalue_vp, false, NIL, qi::_1)] |
517  boolean[_val = phx::bind(xvalue_vp, false, BOOL, qi::_1)] |
518  number[_val = phx::bind(xvalue_vp, false, NUMBER, qi::_1)] |
519  complex[_val = phx::bind(xvalue_vp, false, COMPLEX, qi::_1)] |
520  string[_val = phx::bind(xvalue_vp, false, STRING, qi::_1)] |
521  sequence[_val = phx::bind(xvalue_vp, false, SEQUENCE, qi::_1)] |
522  table[_val = phx::bind(xvalue_vp, false, TABLE, qi::_1)] |
523  id[_val = phx::bind(xvalue_vp, false, TABLEID, qi::_1)] |
524  catchall[_val = phx::bind(xvalue_vp, false, STRING, qi::_1)]);
525  nil.name("nil token");
526  boolean.name("boolean token");
527  inf.name("inf token");
528  squoted.name("squoted token");
529  dquoted.name("dquoted token");
530  number.name("number atom");
531  string.name("string atom");
532  name.name("name atom");
533  complex.name("complex atom");
534  sequence.name("sequence");
535  table.name("table");
536  id.name("id atom");
537  value.name("value");
538  catchall.name("catchall atom");
539  } // value_parser c'tor
540 
541  // ----------------------------------------------------------------------
542 
543  document_parser::document_parser(cet::includer const& s)
544  : document_parser::base_type{document}, sref{s}
545  {
546  name = fhicl::ass;
547  qualname =
548  fhicl::ass[_val = qi::_1] >>
549  *((char_('.') > fhicl::ass)[_val += qi::_1 + qi::_2] |
550  (char_('[') > fhicl::uint >
551  char_(']'))[_val += qi::_1 + qi::_2 + qi::_3]); // Whitespace permitted
552  // before, and around
553  // delimiters ( '.',
554  // '[', ']').
555  noskip_qualname =
556  no_skip[fhicl::ass][_val = qi::_1] >>
557  *((char_('.') > fhicl::ass)[_val += qi::_1 + qi::_2] |
558  (char_('[') > fhicl::uint >
559  char_(']'))[_val += qi::_1 + qi::_2 + qi::_3]); // Whitespace permitted
560  // around delimiters
561  // ('.', '[', ']')
562  // only.
563  localref = lit("@local::") > noskip_qualname;
564  dbref = lit("@db::") > noskip_qualname;
565  // Can't use simple, "list context" due to the possibility of one of
566  // the list elements actually returning multiple elements.
567  sequence =
568  lit('[') >
569  -(((value[phx::bind(seq_insert_value, ref(qi::_1), _val)]) |
570  ((iter_pos >> lit("@sequence::")) >
571  noskip_qualname)[phx::bind(&document_parser::seq_insert_sequence,
572  this,
573  ref(qi::_2),
574  _val,
575  qi::_1)])) >
576  *(lit(',') >
577  ((value[phx::bind(seq_insert_value, ref(qi::_1), _val)]) |
578  ((iter_pos >> lit("@sequence::")) >
579  noskip_qualname)[phx::bind(&document_parser::seq_insert_sequence,
580  this,
581  ref(qi::_2),
582  _val,
583  qi::_1)])) > lit(']');
584  table =
585  lit('{') >
586  *((iter_pos >> name >> fhicl::binding >> value)[phx::bind(&map_insert_loc,
587  ref(qi::_2),
588  qi::_3,
589  ref(qi::_4),
590  _val,
591  qi::_1,
592  sref)] |
593  (iter_pos >> name >> (lit(':') > lit("@erase")))[phx::bind(
594  &map_erase_loc, ref(qi::_2), _val, qi::_1, sref)] |
595  ((iter_pos >> lit("@table::")) >
596  noskip_qualname)[phx::bind(&document_parser::insert_table_in_table,
597  this,
598  ref(qi::_2),
599  _val,
600  qi::_1)]) > lit('}');
601  // Clang does not like this (multiple unsequenced modifications to '_val'
602  // [-Werror,-Wunsequenced]) TEMPORARILY wrap until validity checked
603 #ifdef __clang__
604 #pragma clang diagnostic push
605 #pragma clang diagnostic ignored "-Wunsequenced"
606 #endif
607  value =
608  ((iter_pos >> vp.nil)[_val = xvalue_for(NIL)] |
609  (iter_pos >> vp.boolean)[_val = xvalue_for(BOOL)] |
610  (iter_pos >> vp.number)[_val = xvalue_for(NUMBER)] |
611  (iter_pos >> vp.complex)[_val = xvalue_for(COMPLEX)] |
612  (iter_pos >> vp.string)[_val = xvalue_for(STRING)] |
613  (iter_pos >>
614  localref)[_val = phx::bind(
615  &document_parser::local_lookup, this, qi::_2, qi::_1)] |
616  (iter_pos >> dbref)[_val = phx::bind(
617  &document_parser::database_lookup, this, qi::_1)] |
618  (iter_pos >> vp.id)[_val = xvalue_for(TABLEID)] |
619  (iter_pos >> sequence)[_val = xvalue_for(SEQUENCE)] |
620  (iter_pos >> table)[_val = xvalue_for(TABLE)] |
621  (iter_pos >> vp.catchall)[_val = xvalue_for(STRING)]);
622 #ifdef __clang__
623 #pragma clang diagnostic pop
624 #endif
625  prolog =
626  lit("BEGIN_PROLOG")[phx::bind(
627  &document_parser::set_in_prolog, this, true)] >
628  *((iter_pos >> qualname >> fhicl::binding >>
629  value)[phx::bind(&document_parser::tbl_insert,
630  this,
631  ref(qi::_2),
632  qi::_3,
633  ref(qi::_4),
634  qi::_1)] |
635  (iter_pos >> qualname >> (lit(':') > lit("@erase")))[phx::bind(
636  &document_parser::tbl_erase, this, qi::_2, qi::_1)] |
637  ((iter_pos >> lit("@table::")) > noskip_qualname)[phx::bind(
638  &document_parser::insert_table, this, qi::_2, qi::_1)]) >
639  lit(
640  "END_PROLOG")[phx::bind(&document_parser::set_in_prolog, this, false)];
641  document = (*prolog) >>
642  *((iter_pos >> qualname >> fhicl::binding >>
643  value)[phx::bind(&document_parser::tbl_insert,
644  this,
645  ref(qi::_2),
646  qi::_3,
647  ref(qi::_4),
648  qi::_1)] |
649  (iter_pos >> qualname >> (lit(':') > lit("@erase")))[phx::bind(
650  &document_parser::tbl_erase, this, qi::_2, qi::_1)] |
651  ((iter_pos >> lit("@table::")) > noskip_qualname)[phx::bind(
652  &document_parser::insert_table, this, qi::_2, qi::_1)]);
653  name.name("name atom");
654  localref.name("localref atom");
655  dbref.name("dbref atom");
656  qualname.name("qualified name");
657  noskip_qualname.name("qualified name (no pre-skip)");
658  sequence.name("sequence");
659  table.name("table");
660  value.name("value");
661  prolog.name("prolog");
662  document.name("document");
663  } // document_parser c'tor
664 }
665 
666 // ----------------------------------------------------------------------
667 
668 bool
672 {
673  using ws_t = qi::rule<FwdIter>;
674  ws_t whitespace = space | lit('#') >> *(char_ - eol) >> eol |
675  lit("//") >> *(char_ - eol) >> eol;
676  value_parser<ws_t> p;
677  auto begin = s.begin();
678  auto const end = s.end();
679  bool const b =
680  qi::phrase_parse(begin, end, p >> *whitespace, whitespace, result) &&
681  begin == end;
682  unparsed = std::string(begin, end);
683  return b;
684 } // parse_value_string()
685 
686 // ----------------------------------------------------------------------
687 
688 namespace {
690  parse_document_(cet::includer s)
691  {
692  qi::rule<iter_t> whitespace = space | lit('#') >> *(char_ - eol) >> eol |
693  lit("//") >> *(char_ - eol) >> eol;
694  document_parser p(s);
695  auto begin = s.begin();
696  auto const end = s.end();
697  bool b = false;
698  try {
699  b = qi::phrase_parse(begin, end, p, whitespace);
700  }
701  catch (qi::expectation_failure<iter_t> const& e) {
702  begin = e.first;
703  }
704  std::string const unparsed(begin, end);
705  if (b && unparsed.empty()) {
706  return std::move(p.tbl);
707  }
708 
709  auto e = fhicl::exception(fhicl::parse_error, "detected at or near")
710  << s.highlighted_whereis(begin) << "\n";
711  using namespace std::string_literals;
712  if (unparsed.find("BEGIN_PROLOG"s) == 0ull) {
713  e << "PROLOG blocks must be both contiguous and not nested.\n";
714  }
715  throw e;
716  }
717 }
718 
721 {
722  return parse_document_(cet::includer{filename, maker});
723 }
724 
727 {
728  return parse_document_(cet::includer(is, maker));
729 }
730 
733 {
734  std::istringstream is{s};
736  return parse_document(is, m);
737 }
738 
739 // ======================================================================
static QCString name
Definition: declinfo.cpp:673
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
intermediate_table::complex_t complex_t
size_t erase(Key const &key)
Definition: stdmap_shims.h:253
const_iterator end() const
Definition: includer.h:40
bool parse_value_string(std::string const &s, extended_value &v, std::string &unparsed)
Definition: parse.cc:669
bool canonical_number(std::string const &value, std::string &result)
static QCString result
std::string dquoted(std::string const &s)
bool is_a(value_tag const t) const noexcept
std::string string
Definition: nybbler.cc:12
def graph(desc, maker=maker)
Definition: apa.py:294
const_iterator begin() const
Definition: includer.h:35
intermediate_table::const_iterator const_iterator
Raw data description.
auto lit(char arg)
Definition: parse_shims.h:11
QTextStream & hex(QTextStream &s)
std::string highlighted_whereis(const_iterator const &it) const
Definition: includer.cc:155
int find(char c, int index=0, bool cs=TRUE) const
Definition: qcstring.cpp:41
string filename
Definition: train.py:213
#define eol
iterator end()
Definition: stdmap_shims.h:171
const double e
std::string src_whereis(const_iterator const &it) const
Definition: includer.cc:176
void set_src_info(std::string const &src)
def key(type, name=None)
Definition: graph.py:13
def move(depos, offset)
Definition: depos.py:107
p
Definition: test.py:223
static int max(int a, int b)
static std::string canon_nil()
Definition: coding.cc:30
extended_value::table_t table_t
Definition: parse.cc:73
fhicl::extended_value::sequence_t sequence_t
intermediate_table::atom_t atom_t
extended_value::atom_t atom_t
Definition: parse.cc:70
bool canonical_string(std::string const &str, std::string &result)
std::string squoted(std::string const &s)
intermediate_table parse_document(std::string const &filename, cet::filepath_maker &maker)
Definition: parse.cc:720
QTextStream & bin(QTextStream &s)
static bool * b
Definition: config.cpp:1043
Protection
Definition: types.h:26
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
std::string pretty_src_info() const
extended_value::complex_t complex_t
Definition: parse.cc:71
std::string::const_iterator const_iterator
Definition: includer.h:27
def maker(G, ac, typename)
Definition: apa.py:280
unsigned uint
Definition: qglobal.h:351
void set_prolog(bool new_prolog_state)
iterator find(Key const &key)
Definition: stdmap_shims.h:225
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
static QCString * s
Definition: config.cpp:1042
static QCString str
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
extended_value::sequence_t sequence_t
Definition: parse.cc:72