AirTSP Logo  1.01.6
C++ Simulated Airline Travel Solution Provider (TSP) Library
OnDParserHelper.cpp
Go to the documentation of this file.
1 // //////////////////////////////////////////////////////////////////////
2 // Import section
3 // //////////////////////////////////////////////////////////////////////
4 // STL
5 #include <cassert>
6 // StdAir
7 #include <stdair/basic/BasFileMgr.hpp>
8 #include <stdair/bom/BomRoot.hpp>
9 #include <stdair/service/Logger.hpp>
10 // AirTSP
13 
14 namespace AIRTSP {
15 
16  namespace OnDParserHelper {
17 
18  // //////////////////////////////////////////////////////////////////////
19  //
20  // Semantic actions
21  //
22  // //////////////////////////////////////////////////////////////////////
23 
26  : _onDPeriod (ioOnDPeriod) {
27  }
28 
29  // //////////////////////////////////////////////////////////////////////
31  : ParserSemanticAction (ioOnDPeriod) {
32  }
33 
34  // //////////////////////////////////////////////////////////////////////
36  iterator_t iStrEnd) const {
37  std::string lOrigin (iStr, iStrEnd);
38  //STDAIR_LOG_DEBUG ( "Origin: " << lOrigin << std::endl);
39 
40  // Set the origin
41  _onDPeriod._origin = lOrigin;
46  _onDPeriod._classCodeList.clear();
47  }
48 
49  // //////////////////////////////////////////////////////////////////////
51  : ParserSemanticAction (ioOnDPeriod) {
52  }
53 
54  // //////////////////////////////////////////////////////////////////////
56  iterator_t iStrEnd) const {
57  std::string lDestination (iStr, iStrEnd);
58  //STDAIR_LOG_DEBUG ("Destination: " << lDestination << std::endl);
59 
60  // Set the destination
61  _onDPeriod._destination = lDestination;
62  }
63 
64  // //////////////////////////////////////////////////////////////////////
67  : ParserSemanticAction (ioOnDPeriod) {
68  }
69 
70  // //////////////////////////////////////////////////////////////////////
72  iterator_t iStrEnd) const {
74  /*STDAIR_LOG_DEBUG ("Date Range Start: "
75  << _onDPeriod._dateRangeStart << std::endl);*/
76 
77  // Reset the number of seconds
79  }
80 
81  // //////////////////////////////////////////////////////////////////////
84  : ParserSemanticAction (ioOnDPeriod) {
85  }
86 
87  // //////////////////////////////////////////////////////////////////////
89  iterator_t iStrEnd) const {
90  // As a Boost date period (COM::DatePeriod_T) defines the last day of
91  // the period to be end-date - one day, we have to add one day to that
92  // end date before.
93  const stdair::DateOffset_T oneDay (1);
95  /*STDAIR_LOG_DEBUG ( "Date Range End: "
96  << _onDPeriod._dateRangeEnd << std::endl);*/
97 
98  // Transform the date pair (i.e., the date range) into a date period
100  stdair::DatePeriod_T (_onDPeriod._dateRangeStart,
102 
103  // Reset the number of seconds
105  }
106 
107  // //////////////////////////////////////////////////////////////////////
110  : ParserSemanticAction (ioOnDPeriod) {
111  }
112 
113  // //////////////////////////////////////////////////////////////////////
115  iterator_t iStrEnd) const {
117 
118  // Reset the number of seconds
120  }
121 
122  // //////////////////////////////////////////////////////////////////////
125  : ParserSemanticAction (ioOnDPeriod) {
126  }
127 
128  // //////////////////////////////////////////////////////////////////////
130  iterator_t iStrEnd) const {
132 
133  // Reset the number of seconds
135  }
136 
137  // //////////////////////////////////////////////////////////////////////
140  : ParserSemanticAction (ioOnDPeriod) {
141  }
142 
143  // //////////////////////////////////////////////////////////////////////
145  iterator_t iStrEnd) const {
146  const std::string lAirlineCodeStr (iStr, iStrEnd);
147  const stdair::AirlineCode_T lAirlineCode(lAirlineCodeStr);
148  // Test if the OnD Period Struct stands for interline products
149  if (_onDPeriod._airlineCodeList.size() > 0) {
150  // update the airline code
151  std::ostringstream ostr;
152  ostr << _onDPeriod._airlineCode << lAirlineCode;
153  _onDPeriod._airlineCode = ostr.str();
154  // Update the number of airlines if necessary
155  const stdair::AirlineCode_T lPreviousAirlineCode =
157  if (lPreviousAirlineCode != lAirlineCode) {
159  }
160  }
161  else {
162  _onDPeriod._airlineCode = lAirlineCode;
164  }
165  _onDPeriod._airlineCodeList.push_back (lAirlineCode);
166 
167  //STDAIR_LOG_DEBUG ( "Airline code: " << lAirlineCode << std::endl);
168  }
169 
170  // //////////////////////////////////////////////////////////////////////
173  : ParserSemanticAction (ioOnDPeriod) {
174  }
175 
176  // //////////////////////////////////////////////////////////////////////
177  void storeClassCode::operator() (char iChar) const {
178  std::ostringstream ostr;
179  ostr << iChar;
180  std::string classCodeStr = ostr.str();
181  const stdair::ClassCode_T lClassCode (classCodeStr);
182  _onDPeriod._classCodeList.push_back(lClassCode);
183  /*STDAIR_LOG_DEBUG ("Class Code: "
184  << lClassCode << std::endl);*/
185  // Insertion of this class Code in the whole classCode name
186  std::ostringstream ostrr;
187  ostrr << _onDPeriod._classCode << classCodeStr;
188  _onDPeriod._classCode = ostrr.str();
189 
190  }
191 
192  // //////////////////////////////////////////////////////////////////////
193  doEndOnD::doEndOnD (stdair::BomRoot& ioBomRoot, OnDPeriodStruct& ioOnDPeriod)
194  : ParserSemanticAction (ioOnDPeriod),
195  _bomRoot (ioBomRoot) {
196  }
197 
198  // //////////////////////////////////////////////////////////////////////
199  void doEndOnD::operator() (iterator_t iStr, iterator_t iStrEnd) const {
200 
201  // DEBUG: Display the result
202  // STDAIR_LOG_DEBUG ("FareRule " << _onDPeriod.describe());
203 
204  // Generation of the O&D-Period object.
205  OnDPeriodGenerator::createOnDPeriod (_bomRoot, _onDPeriod);
206  }
207 
208  // ///////////////////////////////////////////////////////////////////////
209  //
210  // Utility Parsers
211  //
212  // ///////////////////////////////////////////////////////////////////////
213 
216 
219 
222 
224  chset_t alpha_cap_set_p ("A-Z");
225 
227  repeat_p_t airport_p (chset_t("0-9A-Z").derived(), 3, 3);
228 
230  repeat_p_t airline_code_p (alpha_cap_set_p.derived(), 2, 3);
231 
233  bounded4_p_t year_p (uint4_p.derived(), 2000u, 2099u);
234 
236  bounded2_p_t month_p (uint2_p.derived(), 1u, 12u);
237 
239  bounded2_p_t day_p (uint2_p.derived(), 1u, 31u);
240 
242  bounded2_p_t hours_p (uint2_p.derived(), 0u, 23u);
243 
245  bounded2_p_t minutes_p (uint2_p.derived(), 0u, 59u);
246 
248  bounded2_p_t seconds_p (uint2_p.derived(), 0u, 59u);
249 
251  chset_t class_code_p ("A-Z");
252 
254  //
255  // (Boost Spirit) Grammar Definition
256  //
258 
259  // //////////////////////////////////////////////////////////////////////
261  OnDParser (stdair::BomRoot& ioBomRoot, OnDPeriodStruct& ioOnDPeriod)
262  : _bomRoot (ioBomRoot), _onDPeriod (ioOnDPeriod) {
263  }
264 
265  // //////////////////////////////////////////////////////////////////////
266  template<typename ScannerT>
268 
269  ond_list = *( boost::spirit::classic::comment_p("//")
270  | boost::spirit::classic::comment_p("/*", "*/")
271  | ond )
272  ;
273 
274  ond = ond_key
275  >> +( ';' >> segment )
276  >> ond_end[doEndOnD(self._bomRoot, self._onDPeriod)]
277  ;
278 
279  ond_end = boost::spirit::classic::ch_p(';')
280  ;
281 
282  ond_key = (airport_p)[storeOrigin(self._onDPeriod)]
283  >> ';' >> (airport_p)[storeDestination(self._onDPeriod)]
284  >> ';' >> date[storeDateRangeStart(self._onDPeriod)]
285  >> ';' >> date[storeDateRangeEnd(self._onDPeriod)]
286  >> ';' >> time[storeStartRangeTime(self._onDPeriod)]
287  >> ';' >> time[storeEndRangeTime(self._onDPeriod)]
288  ;
289 
290  date = boost::spirit::classic::
291  lexeme_d[(year_p)[boost::spirit::classic::
292  assign_a(self._onDPeriod._itYear)]
293  >> '-'
294  >> (month_p)[boost::spirit::classic::
295  assign_a(self._onDPeriod._itMonth)]
296  >> '-'
297  >> (day_p)[boost::spirit::classic::
298  assign_a(self._onDPeriod._itDay)]]
299  ;
300 
301  time = boost::spirit::classic::
302  lexeme_d[(hours_p)[boost::spirit::classic::
303  assign_a(self._onDPeriod._itHours)]
304  >> ':'
305  >> (minutes_p)[boost::spirit::classic::
306  assign_a(self._onDPeriod._itMinutes)]
307  >> !(':' >> (seconds_p)[boost::spirit::classic::
308  assign_a(self._onDPeriod._itSeconds)])]
309  ;
310 
311  segment = boost::spirit::classic::
312  lexeme_d[(airline_code_p)[storeAirlineCode(self._onDPeriod)]]
313  >> ';' >> (class_code_p)[storeClassCode(self._onDPeriod)]
314  ;
315 
316  //BOOST_SPIRIT_DEBUG_NODE (OnDParser);
317  BOOST_SPIRIT_DEBUG_NODE (ond_list);
318  BOOST_SPIRIT_DEBUG_NODE (ond);
319  BOOST_SPIRIT_DEBUG_NODE (segment);
320  BOOST_SPIRIT_DEBUG_NODE (ond_key);
321  BOOST_SPIRIT_DEBUG_NODE (ond_end);
322  BOOST_SPIRIT_DEBUG_NODE (date);
323  BOOST_SPIRIT_DEBUG_NODE (time);
324 
325  }
326 
327  // //////////////////////////////////////////////////////////////////////
328  template<typename ScannerT>
329  boost::spirit::classic::rule<ScannerT> const&
331  return ond_list;
332  }
333  }
334 
336  //
337  // Entry class for the file parser
338  //
340 
341  // //////////////////////////////////////////////////////////////////////
342  OnDPeriodFileParser::OnDPeriodFileParser (const stdair::Filename_T& iFilename,
343  stdair::BomRoot& ioBomRoot)
344  : _filename (iFilename), _bomRoot (ioBomRoot) {
345  init();
346  }
347 
348  // //////////////////////////////////////////////////////////////////////
349  void OnDPeriodFileParser::init() {
350  // Check that the file exists and is readable
351  const bool doesExistAndIsReadable =
352  stdair::BasFileMgr::doesExistAndIsReadable (_filename);
353 
354  if (doesExistAndIsReadable == false) {
355  STDAIR_LOG_ERROR ("The O&D file " << _filename
356  << " does not exist or can not be read.");
357 
358  throw OnDInputFileNotFoundException ("The O&D file " + _filename
359  + " does not exist or can not be read");
360  }
361 
362  // Open the file
363  _startIterator = iterator_t (_filename);
364 
365  // Check that the filename exists and can be open
366  if (!_startIterator) {
367  STDAIR_LOG_DEBUG ("The O&D file " << _filename << " can not be open."
368  << std::endl);
369  throw OnDInputFileNotFoundException ("The file " + _filename
370  + " does not exist or can not be read");
371  }
372 
373  // Create an EOF iterator
374  _endIterator = _startIterator.make_end();
375  }
376 
377  // //////////////////////////////////////////////////////////////////////
379  bool oResult = false;
380 
381  STDAIR_LOG_DEBUG ("Parsing O&D input file: " << _filename);
382 
383  // Initialise the parser (grammar) with the helper/staging structure.
384  OnDParserHelper::OnDParser lODParser (_bomRoot, _onDPeriod);
385 
386  // Launch the parsing of the file and, thanks to the doEndOnD
387  // call-back structure, filling the worldSchedule (Fares)
388  boost::spirit::classic::parse_info<iterator_t> info =
389  boost::spirit::classic::parse (_startIterator, _endIterator, lODParser,
390  boost::spirit::classic::space_p);
391 
392  // Retrieves whether or not the parsing was successful
393  oResult = info.hit;
394 
395  const std::string hasBeenFullyReadStr = (info.full == true)?"":"not ";
396  if (oResult == true) {
397  STDAIR_LOG_DEBUG ("Parsing of O&D input file: " << _filename
398  << " succeeded: read " << info.length
399  << " characters. The input file has "
400  << hasBeenFullyReadStr
401  << "been fully read. Stop point: " << info.stop);
402 
403  } else {
404  // TODO: decide whether to throw an exception
405  STDAIR_LOG_ERROR ("Parsing of O&D input file: " << _filename
406  << " failed: read " << info.length
407  << " characters. The input file has "
408  << hasBeenFullyReadStr
409  << "been fully read. Stop point: " << info.stop);
410  }
411 
412  return oResult;
413  }
414 }
AIRTSP::OnDParserHelper::uint4_p
uint4_p_t uint4_p
Definition: OnDParserHelper.cpp:218
AIRTSP::OnDParserHelper::OnDParser::definition::definition
definition(OnDParser const &self)
Definition: OnDParserHelper.cpp:267
AIRTSP::uint4_p_t
boost::spirit::classic::uint_parser< unsigned int, 10, 4, 4 > uint4_p_t
Definition: BasParserTypes.hpp:51
AIRTSP::OnDPeriodStruct::_dateRangeStart
stdair::Date_T _dateRangeStart
Definition: OnDPeriodStruct.hpp:54
AIRTSP::OnDParserHelper::storeStartRangeTime::storeStartRangeTime
storeStartRangeTime(OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:109
AIRTSP::OnDParserHelper::day_p
bounded2_p_t day_p(uint2_p.derived(), 1u, 31u)
AIRTSP::OnDParserHelper::minutes_p
bounded2_p_t minutes_p(uint2_p.derived(), 0u, 59u)
AIRTSP::iterator_t
boost::spirit::classic::file_iterator< char_t > iterator_t
Definition: BasParserTypes.hpp:35
AIRTSP::OnDParserHelper::storeEndRangeTime::operator()
void operator()(iterator_t iStr, iterator_t iStrEnd) const
Definition: OnDParserHelper.cpp:129
AIRTSP::OnDParserHelper::storeDestination::operator()
void operator()(iterator_t iStr, iterator_t iStrEnd) const
Definition: OnDParserHelper.cpp:55
AIRTSP::OnDParserHelper::storeClassCode::operator()
void operator()(char iChar) const
Definition: OnDParserHelper.cpp:177
OnDPeriodGenerator.hpp
AIRTSP::OnDPeriodStruct::_nbOfAirlines
stdair::NbOfAirlines_T _nbOfAirlines
Definition: OnDPeriodStruct.hpp:47
AIRTSP::OnDPeriodStruct::_airlineCodeList
stdair::AirlineCodeList_T _airlineCodeList
Definition: OnDPeriodStruct.hpp:50
AIRTSP::OnDPeriodFileParser::generateOnDPeriods
bool generateOnDPeriods()
Definition: OnDParserHelper.cpp:378
AIRTSP::OnDParserHelper::doEndOnD::_bomRoot
stdair::BomRoot & _bomRoot
Definition: OnDParserHelper.hpp:112
AIRTSP::OnDPeriodStruct::getDate
stdair::Date_T getDate() const
Definition: OnDPeriodStruct.cpp:28
AIRTSP::OnDParserHelper::doEndOnD
Definition: OnDParserHelper.hpp:106
AIRTSP::chset_t
boost::spirit::classic::chset< char_t > chset_t
Definition: BasParserTypes.hpp:57
AIRTSP::OnDParserHelper::hours_p
bounded2_p_t hours_p(uint2_p.derived(), 0u, 23u)
AIRTSP::OnDParserHelper::seconds_p
bounded2_p_t seconds_p(uint2_p.derived(), 0u, 59u)
AIRTSP::OnDParserHelper::ParserSemanticAction::_onDPeriod
OnDPeriodStruct & _onDPeriod
Definition: OnDParserHelper.hpp:38
AIRTSP::OnDPeriodStruct::_timeRangeStart
stdair::Duration_T _timeRangeStart
Definition: OnDPeriodStruct.hpp:45
AIRTSP::OnDParserHelper::OnDParser
Definition: OnDParserHelper.hpp:127
AIRTSP::OnDParserHelper::storeClassCode
Definition: OnDParserHelper.hpp:98
AIRTSP::OnDParserHelper::storeDateRangeEnd::operator()
void operator()(iterator_t iStr, iterator_t iStrEnd) const
Definition: OnDParserHelper.cpp:88
AIRTSP::OnDParserHelper::class_code_p
chset_t class_code_p("A-Z")
AIRTSP::OnDParserHelper::uint1_4_p
uint1_4_p_t uint1_4_p
Definition: OnDParserHelper.cpp:221
AIRTSP::OnDParserHelper::alpha_cap_set_p
chset_t alpha_cap_set_p("A-Z")
AIRTSP::OnDParserHelper::storeDestination::storeDestination
storeDestination(OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:50
AIRTSP::OnDPeriodStruct::_destination
stdair::AirportCode_T _destination
Definition: OnDPeriodStruct.hpp:43
AIRTSP::OnDPeriodStruct::_airlineCode
stdair::AirlineCode_T _airlineCode
Definition: OnDPeriodStruct.hpp:48
AIRTSP::OnDPeriodStruct::_itSeconds
long _itSeconds
Definition: OnDPeriodStruct.hpp:63
AIRTSP::OnDPeriodStruct::_classCodeList
stdair::ClassCodeList_T _classCodeList
Definition: OnDPeriodStruct.hpp:51
AIRTSP::OnDParserHelper::storeAirlineCode::operator()
void operator()(iterator_t iStr, iterator_t iStrEnd) const
Definition: OnDParserHelper.cpp:144
AIRTSP::OnDParserHelper::storeAirlineCode
Definition: OnDParserHelper.hpp:90
AIRTSP::OnDPeriodStruct::_timeRangeEnd
stdair::Duration_T _timeRangeEnd
Definition: OnDPeriodStruct.hpp:46
AIRTSP::OnDPeriodStruct::_classCode
stdair::ClassCode_T _classCode
Definition: OnDPeriodStruct.hpp:49
AIRTSP::OnDParserHelper::OnDParser::OnDParser
OnDParser(stdair::BomRoot &, OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:261
AIRTSP::OnDParserHelper::storeStartRangeTime
Definition: OnDParserHelper.hpp:74
AIRTSP::OnDParserHelper::storeDateRangeEnd::storeDateRangeEnd
storeDateRangeEnd(OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:83
AIRTSP::repeat_p_t
boost::spirit::classic::impl::loop_traits< chset_t, unsigned int, unsigned int >::type repeat_p_t
Definition: BasParserTypes.hpp:63
AIRTSP
Definition: AIRTSP_Service.hpp:23
AIRTSP::OnDParserHelper::storeDateRangeStart
Definition: OnDParserHelper.hpp:58
AIRTSP::OnDParserHelper::storeOrigin::operator()
void operator()(iterator_t iStr, iterator_t iStrEnd) const
Definition: OnDParserHelper.cpp:35
AIRTSP::bounded2_p_t
boost::spirit::classic::bounded< uint2_p_t, unsigned int > bounded2_p_t
Definition: BasParserTypes.hpp:66
AIRTSP::OnDParserHelper::month_p
bounded2_p_t month_p(uint2_p.derived(), 1u, 12u)
AIRTSP::OnDPeriodFileParser::OnDPeriodFileParser
OnDPeriodFileParser(const stdair::Filename_T &iFilename, stdair::BomRoot &ioBomRoot)
Definition: OnDParserHelper.cpp:342
AIRTSP::OnDParserHelper::storeDateRangeEnd
Definition: OnDParserHelper.hpp:66
AIRTSP::OnDParserHelper::doEndOnD::doEndOnD
doEndOnD(stdair::BomRoot &, OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:193
AIRTSP::OnDParserHelper::storeOrigin
Definition: OnDParserHelper.hpp:42
AIRTSP::OnDPeriodStruct::_dateRangeEnd
stdair::Date_T _dateRangeEnd
Definition: OnDPeriodStruct.hpp:55
AIRTSP::OnDPeriodStruct::_origin
stdair::AirportCode_T _origin
Definition: OnDPeriodStruct.hpp:42
AIRTSP::OnDPeriodStruct::getTime
stdair::Duration_T getTime() const
Definition: OnDPeriodStruct.cpp:33
OnDParserHelper.hpp
AIRTSP::OnDPeriodStruct::_datePeriod
stdair::DatePeriod_T _datePeriod
Definition: OnDPeriodStruct.hpp:44
AIRTSP::OnDParserHelper::uint2_p
uint2_p_t uint2_p
Definition: OnDParserHelper.cpp:215
AIRTSP::OnDParserHelper::ParserSemanticAction
Definition: OnDParserHelper.hpp:34
AIRTSP::OnDParserHelper::storeOrigin::storeOrigin
storeOrigin(OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:30
AIRTSP::OnDInputFileNotFoundException
Definition: AIRTSP_Types.hpp:35
AIRTSP::OnDParserHelper::storeEndRangeTime::storeEndRangeTime
storeEndRangeTime(OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:124
AIRTSP::OnDParserHelper::doEndOnD::operator()
void operator()(iterator_t iStr, iterator_t iStrEnd) const
Definition: OnDParserHelper.cpp:199
AIRTSP::OnDParserHelper::airline_code_p
repeat_p_t airline_code_p(alpha_cap_set_p.derived(), 2, 3)
AIRTSP::OnDParserHelper::storeAirlineCode::storeAirlineCode
storeAirlineCode(OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:139
AIRTSP::OnDPeriodStruct
Definition: OnDPeriodStruct.hpp:16
AIRTSP::OnDParserHelper::airport_p
repeat_p_t airport_p(chset_t("0-9A-Z").derived(), 3, 3)
AIRTSP::OnDParserHelper::ParserSemanticAction::ParserSemanticAction
ParserSemanticAction(OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:25
AIRTSP::OnDParserHelper::year_p
bounded4_p_t year_p(uint4_p.derived(), 2000u, 2099u)
AIRTSP::uint1_4_p_t
boost::spirit::classic::uint_parser< unsigned int, 10, 1, 4 > uint1_4_p_t
Definition: BasParserTypes.hpp:54
AIRTSP::OnDParserHelper::storeEndRangeTime
Definition: OnDParserHelper.hpp:82
AIRTSP::OnDParserHelper::storeClassCode::storeClassCode
storeClassCode(OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:172
AIRTSP::bounded4_p_t
boost::spirit::classic::bounded< uint4_p_t, unsigned int > bounded4_p_t
Definition: BasParserTypes.hpp:67
AIRTSP::OnDParserHelper::storeStartRangeTime::operator()
void operator()(iterator_t iStr, iterator_t iStrEnd) const
Definition: OnDParserHelper.cpp:114
AIRTSP::OnDParserHelper::storeDestination
Definition: OnDParserHelper.hpp:50
AIRTSP::OnDParserHelper::OnDParser::definition::start
boost::spirit::classic::rule< ScannerT > const & start() const
Definition: OnDParserHelper.cpp:330
AIRTSP::OnDParserHelper::storeDateRangeStart::storeDateRangeStart
storeDateRangeStart(OnDPeriodStruct &)
Definition: OnDParserHelper.cpp:66
AIRTSP::uint2_p_t
boost::spirit::classic::uint_parser< unsigned int, 10, 2, 2 > uint2_p_t
Definition: BasParserTypes.hpp:48
AIRTSP::OnDParserHelper::storeDateRangeStart::operator()
void operator()(iterator_t iStr, iterator_t iStrEnd) const
Definition: OnDParserHelper.cpp:71