From: <gsa...@us...> - 2010-11-16 10:08:16
|
Revision: 156 http://dsim.svn.sourceforge.net/dsim/?rev=156&view=rev Author: gsabatier Date: 2010-11-16 10:08:08 +0000 (Tue, 16 Nov 2010) Log Message: ----------- [Boost Test] Tests for the Spirit v2 parser are mow implemented Modified Paths: -------------- trunk/dsim/test/boost/Makefile.am trunk/dsim/test/boost/spirit/Makefile.am trunk/dsim/test/boost/spirit/world_schedule.csv trunk/dsim/test/boost/spiritQi/schedule_parser.cpp trunk/dsim/test/boost/spiritQi/world_schedule.csv Removed Paths: ------------- trunk/dsim/test/boost/spirit/action_parser.cpp trunk/dsim/test/boost/spirit/bad_input.csv trunk/dsim/test/boost/spirit/complex_parser.cpp trunk/dsim/test/boost/spirit/employee_parser.cpp trunk/dsim/test/boost/spirit/good_input.csv trunk/dsim/test/boost/spirit/num_list1_parser.cpp trunk/dsim/test/boost/spirit/roman_parser.cpp trunk/dsim/test/boost/spirit/stream_iterator_parser.cpp trunk/dsim/test/boost/spirit/sum_parser.cpp Modified: trunk/dsim/test/boost/Makefile.am =================================================================== --- trunk/dsim/test/boost/Makefile.am 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/Makefile.am 2010-11-16 10:08:08 UTC (rev 156) @@ -5,7 +5,7 @@ MAINTAINERCLEANFILES = Makefile.in ## -SUBDIRS = accumulators asio filesystem intrusive mpi mpl \ +SUBDIRS = accumulators asio filesystem intrusive mpl \ serialization signals spirit spiritQi smart_pointers EXTRA_DIST = Modified: trunk/dsim/test/boost/spirit/Makefile.am =================================================================== --- trunk/dsim/test/boost/spirit/Makefile.am 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/Makefile.am 2010-11-16 10:08:08 UTC (rev 156) @@ -3,42 +3,44 @@ MAINTAINERCLEANFILES = Makefile.in -check_PROGRAMS = employee_parser action_parser complex_parser \ - num_list1_parser roman_parser sum_parser \ - schedule_parser stream_iterator_parser levenshtein +check_PROGRAMS = full_calculator functor_parser number_parser \ + parameter_parser spirit_parser subrule_parser \ + schedule_parser search_string_parser levenshtein -levenshtein_SOURCES = levenshtein.cpp -levenshtein_CXXFLAGS = -levenshtein_LDFLAGS = +full_calculator_SOURCES = full_calculator.cpp +full_calculator_CXXFLAGS = $(BOOST_CFLAGS) +full_calculator_LDADD = $(BOOST_LIBS) -employee_parser_SOURCES = employee_parser.cpp -employee_parser_CXXFLAGS = $(BOOST_CFLAGS) -employee_parser_LDADD = $(BOOST_LIBS) +functor_parser_SOURCES = functor_parser.cpp +functor_parser_CXXFLAGS = $(BOOST_CFLAGS) +functor_parser_LDADD = $(BOOST_LIBS) -action_parser_SOURCES = action_parser.cpp -action_parser_CXXFLAGS = $(BOOST_CFLAGS) -action_parser_LDADD = $(BOOST_LIBS) +number_parser_SOURCES = number_parser.cpp +number_parser_CXXFLAGS = $(BOOST_CFLAGS) +number_parser_LDADD = $(BOOST_LIBS) -complex_parser_SOURCES = complex_parser.cpp -complex_parser_CXXFLAGS = $(BOOST_CFLAGS) -complex_parser_LDADD = $(BOOST_LIBS) +parameter_parser_SOURCES = parameter_parser.cpp +parameter_parser_CXXFLAGS = $(BOOST_CFLAGS) +parameter_parser_LDADD = $(BOOST_LIBS) -num_list1_parser_SOURCES = num_list1_parser.cpp -num_list1_parser_CXXFLAGS = $(BOOST_CFLAGS) -num_list1_parser_LDADD = $(BOOST_LIBS) +spirit_parser_SOURCES = spirit_parser.cpp +spirit_parser_CXXFLAGS = $(BOOST_CFLAGS) +spirit_parser_LDADD = $(BOOST_LIBS) -roman_parser_SOURCES = roman_parser.cpp -roman_parser_CXXFLAGS = $(BOOST_CFLAGS) -roman_parser_LDADD = $(BOOST_LIBS) +subrule_parser_SOURCES = subrule_parser.cpp +subrule_parser_CXXFLAGS = $(BOOST_CFLAGS) +subrule_parser_LDADD = $(BOOST_LIBS) -sum_parser_SOURCES = sum_parser.cpp -sum_parser_CXXFLAGS = $(BOOST_CFLAGS) -sum_parser_LDADD = $(BOOST_LIBS) - schedule_parser_SOURCES = schedule_parser.cpp schedule_parser_CXXFLAGS = $(BOOST_CFLAGS) schedule_parser_LDADD = $(BOOST_LIBS) $(BOOST_DATE_TIME_LIB) -stream_iterator_parser_SOURCES = stream_iterator_parser.cpp -stream_iterator_parser_CXXFLAGS = $(BOOST_CFLAGS) -stream_iterator_parser_LDADD = $(BOOST_LIBS) $(BOOST_DATE_TIME_LIB) +search_string_parser_SOURCES = search_string_parser.cpp +search_string_parser_CXXFLAGS = $(BOOST_CFLAGS) +search_string_parser_LDADD = $(BOOST_LIBS) $(BOOST_DATE_TIME_LIB) + +levenshtein_SOURCES = levenshtein.cpp +levenshtein_LDADD = + +EXTRA_DIST = test_full_calculator.sh test_parameter_parser.sh \ + test_schedule_parser.sh Deleted: trunk/dsim/test/boost/spirit/action_parser.cpp =================================================================== --- trunk/dsim/test/boost/spirit/action_parser.cpp 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/action_parser.cpp 2010-11-16 10:08:08 UTC (rev 156) @@ -1,104 +0,0 @@ -/*============================================================================= - Copyright (c) 2001-2010 Joel de Guzman - - Distributed under the Boost Software License, Version 1.0. (See accompanying - file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -=============================================================================*/ -#include <boost/config/warning_disable.hpp> -#include <boost/spirit/include/qi.hpp> -#include <boost/lambda/lambda.hpp> -#include <boost/bind.hpp> - -#include <iostream> - -// Presented are various ways to attach semantic actions -// * Using plain function pointer -// * Using simple function object -// * Using boost.bind with a plain function -// * Using boost.bind with a member function -// * Using boost.lambda - -//[tutorial_semantic_action_functions -namespace client -{ - namespace qi = boost::spirit::qi; - - // A plain function - void print(int const& i) - { - std::cout << i << std::endl; - } - - // A member function - struct writer - { - void print(int const& i) const - { - std::cout << i << std::endl; - } - }; - - // A function object - struct print_action - { - void operator()(int const& i, qi::unused_type, qi::unused_type) const - { - std::cout << i << std::endl; - } - }; -} -//] - -int main() -{ - using boost::spirit::qi::int_; - using boost::spirit::qi::parse; - using client::print; - using client::writer; - using client::print_action; - - { // example using plain function - - char const *first = "{42}", *last = first + std::strlen(first); - //[tutorial_attach_actions1 - parse(first, last, '{' >> int_[&print] >> '}'); - //] - } - - { // example using simple function object - - char const *first = "{43}", *last = first + std::strlen(first); - //[tutorial_attach_actions2 - parse(first, last, '{' >> int_[print_action()] >> '}'); - //] - } - - { // example using boost.bind with a plain function - - char const *first = "{44}", *last = first + std::strlen(first); - //[tutorial_attach_actions3 - parse(first, last, '{' >> int_[boost::bind(&print, _1)] >> '}'); - //] - } - - { // example using boost.bind with a member function - - char const *first = "{44}", *last = first + std::strlen(first); - //[tutorial_attach_actions4 - writer w; - parse(first, last, '{' >> int_[boost::bind(&writer::print, &w, _1)] >> '}'); - //] - } - - { // example using boost.lambda - - namespace lambda = boost::lambda; - char const *first = "{45}", *last = first + std::strlen(first); - using lambda::_1; - //[tutorial_attach_actions5 - parse(first, last, '{' >> int_[std::cout << _1 << '\n'] >> '}'); - //] - } - - return 0; -} Deleted: trunk/dsim/test/boost/spirit/bad_input.csv =================================================================== --- trunk/dsim/test/boost/spirit/bad_input.csv 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/bad_input.csv 2010-11-16 10:08:08 UTC (rev 156) @@ -1,5 +0,0 @@ -# test -# -# bad input - -123;42.0;a;1.4 Deleted: trunk/dsim/test/boost/spirit/complex_parser.cpp =================================================================== --- trunk/dsim/test/boost/spirit/complex_parser.cpp 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/complex_parser.cpp 2010-11-16 10:08:08 UTC (rev 156) @@ -1,101 +0,0 @@ -/*============================================================================= - Copyright (c) 2002-2010 Joel de Guzman - - Distributed under the Boost Software License, Version 1.0. (See accompanying - file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -=============================================================================*/ -/////////////////////////////////////////////////////////////////////////////// -// -// A complex number micro parser. -// -// [ JDG May 10, 2002 ] spirit1 -// [ JDG May 9, 2007 ] spirit2 -// -/////////////////////////////////////////////////////////////////////////////// - -#include <boost/config/warning_disable.hpp> -#include <boost/spirit/include/qi.hpp> -#include <boost/spirit/include/phoenix_core.hpp> -#include <boost/spirit/include/phoenix_operator.hpp> - -#include <iostream> -#include <string> -#include <complex> - -/////////////////////////////////////////////////////////////////////////////// -// Our complex number parser/compiler -/////////////////////////////////////////////////////////////////////////////// -//[tutorial_complex_number -namespace client -{ - template <typename Iterator> - bool parse_complex(Iterator first, Iterator last, std::complex<double>& c) - { - using boost::spirit::qi::double_; - using boost::spirit::qi::_1; - using boost::spirit::qi::phrase_parse; - using boost::spirit::ascii::space; - using boost::phoenix::ref; - - double rN = 0.0; - double iN = 0.0; - bool r = phrase_parse(first, last, - - // Begin grammar - ( - '(' >> double_[ref(rN) = _1] - >> -(',' >> double_[ref(iN) = _1]) >> ')' - | double_[ref(rN) = _1] - ), - // End grammar - - space); - - if (!r || first != last) // fail if we did not get a full match - return false; - c = std::complex<double>(rN, iN); - return r; - } -} -//] - -//////////////////////////////////////////////////////////////////////////// -// Main program -//////////////////////////////////////////////////////////////////////////// -int -main() -{ - std::cout << "/////////////////////////////////////////////////////////\n\n"; - std::cout << "\t\tA complex number micro parser for Spirit...\n\n"; - std::cout << "/////////////////////////////////////////////////////////\n\n"; - - std::cout << "Give me a complex number of the form r or (r) or (r,i) \n"; - std::cout << "Type [q or Q] to quit\n\n"; - - std::string str; - while (getline(std::cin, str)) - { - if (str.empty() || str[0] == 'q' || str[0] == 'Q') - break; - - std::complex<double> c; - if (client::parse_complex(str.begin(), str.end(), c)) - { - std::cout << "-------------------------\n"; - std::cout << "Parsing succeeded\n"; - std::cout << "got: " << c << std::endl; - std::cout << "\n-------------------------\n"; - } - else - { - std::cout << "-------------------------\n"; - std::cout << "Parsing failed\n"; - std::cout << "-------------------------\n"; - } - } - - std::cout << "Bye... :-) \n\n"; - return 0; -} - - Deleted: trunk/dsim/test/boost/spirit/employee_parser.cpp =================================================================== --- trunk/dsim/test/boost/spirit/employee_parser.cpp 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/employee_parser.cpp 2010-11-16 10:08:08 UTC (rev 156) @@ -1,152 +0,0 @@ - -/*============================================================================= - Copyright (c) 2002-2010 Joel de Guzman - - Distributed under the Boost Software License, Version 1.0. (See accompanying - file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -=============================================================================*/ -/////////////////////////////////////////////////////////////////////////////// -// -// A parser for arbitrary tuples. This example presents a parser -// for an employee structure. -// -// [ JDG May 9, 2007 ] -// -/////////////////////////////////////////////////////////////////////////////// - -#include <boost/config/warning_disable.hpp> -#include <boost/spirit/include/qi.hpp> -#include <boost/spirit/include/phoenix_core.hpp> -#include <boost/spirit/include/phoenix_operator.hpp> -#include <boost/spirit/include/phoenix_object.hpp> -#include <boost/fusion/include/adapt_struct.hpp> -#include <boost/fusion/include/io.hpp> - -#include <iostream> -#include <string> -#include <complex> - -namespace client -{ - namespace qi = boost::spirit::qi; - namespace ascii = boost::spirit::ascii; - - /////////////////////////////////////////////////////////////////////////// - // Our employee struct - /////////////////////////////////////////////////////////////////////////// - //[tutorial_employee_struct - struct employee - { - int age; - std::string surname; - std::string forename; - double salary; - }; - //] -} - -// We need to tell fusion about our employee struct -// to make it a first-class fusion citizen. This has to -// be in global scope. - -//[tutorial_employee_adapt_struct -BOOST_FUSION_ADAPT_STRUCT( - client::employee, - (int, age) - (std::string, surname) - (std::string, forename) - (double, salary) -) -//] - -namespace client -{ - /////////////////////////////////////////////////////////////////////////////// - // Our employee parser - /////////////////////////////////////////////////////////////////////////////// - //[tutorial_employee_parser - template <typename Iterator> - struct employee_parser : qi::grammar<Iterator, employee(), ascii::space_type> - { - employee_parser() : employee_parser::base_type(start) - { - using qi::int_; - using qi::lit; - using qi::double_; - using qi::lexeme; - using ascii::char_; - - quoted_string %= lexeme['"' >> +(char_ - '"') >> '"']; - - start %= - lit("employee") - >> '{' - >> int_ >> ',' - >> quoted_string >> ',' - >> quoted_string >> ',' - >> double_ - >> '}' - ; - } - - qi::rule<Iterator, std::string(), ascii::space_type> quoted_string; - qi::rule<Iterator, employee(), ascii::space_type> start; - }; - //] -} - -//////////////////////////////////////////////////////////////////////////// -// Main program -//////////////////////////////////////////////////////////////////////////// -int -main() -{ - std::cout << "/////////////////////////////////////////////////////////\n\n"; - std::cout << "\t\tAn employee parser for Spirit...\n\n"; - std::cout << "/////////////////////////////////////////////////////////\n\n"; - - std::cout - << "Give me an employee of the form :" - << "employee{age, \"surname\", \"forename\", salary } \n"; - std::cout << "Type [q or Q] to quit\n\n"; - - using boost::spirit::ascii::space; - typedef std::string::const_iterator iterator_type; - typedef client::employee_parser<iterator_type> employee_parser; - - employee_parser g; // Our grammar - std::string str; - while (getline(std::cin, str)) - { - if (str.empty() || str[0] == 'q' || str[0] == 'Q') - break; - - client::employee emp; - std::string::const_iterator iter = str.begin(); - std::string::const_iterator end = str.end(); - bool r = phrase_parse(iter, end, g, space, emp); - - if (r && iter == end) - { - std::cout << boost::fusion::tuple_open('['); - std::cout << boost::fusion::tuple_close(']'); - std::cout << boost::fusion::tuple_delimiter(", "); - - std::cout << "-------------------------\n"; - std::cout << "Parsing succeeded\n"; - std::cout << "got: " << boost::fusion::as_vector(emp) << std::endl; - std::cout << "\n-------------------------\n"; - } - else - { - std::cout << "-------------------------\n"; - std::cout << "Parsing failed\n"; - std::cout << "-------------------------\n"; - } - } - - std::cout << "Bye... :-) \n\n"; - return 0; -} - - Deleted: trunk/dsim/test/boost/spirit/good_input.csv =================================================================== --- trunk/dsim/test/boost/spirit/good_input.csv 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/good_input.csv 2010-11-16 10:08:08 UTC (rev 156) @@ -1,5 +0,0 @@ -# test -# -# good input -8 ; -6; 7; Deleted: trunk/dsim/test/boost/spirit/num_list1_parser.cpp =================================================================== --- trunk/dsim/test/boost/spirit/num_list1_parser.cpp 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/num_list1_parser.cpp 2010-11-16 10:08:08 UTC (rev 156) @@ -1,90 +0,0 @@ -/*============================================================================= - Copyright (c) 2002-2010 Joel de Guzman - - Distributed under the Boost Software License, Version 1.0. (See accompanying - file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -=============================================================================*/ -/////////////////////////////////////////////////////////////////////////////// -// -// This sample demontrates a parser for a comma separated list of numbers. -// No actions. -// -// [ JDG May 10, 2002 ] spirit1 -// [ JDG March 24, 2007 ] spirit2 -// -/////////////////////////////////////////////////////////////////////////////// - -#include <boost/config/warning_disable.hpp> -#include <boost/spirit/include/qi.hpp> - -#include <iostream> -#include <string> -#include <vector> - -namespace client -{ - namespace qi = boost::spirit::qi; - namespace ascii = boost::spirit::ascii; - - /////////////////////////////////////////////////////////////////////////// - // Our number list parser - /////////////////////////////////////////////////////////////////////////// - //[tutorial_numlist1 - template <typename Iterator> - bool parse_numbers(Iterator first, Iterator last) - { - using qi::double_; - using qi::phrase_parse; - using ascii::space; - - bool r = phrase_parse( - first, /*< start iterator >*/ - last, /*< end iterator >*/ - double_ >> *(',' >> double_), /*< the parser >*/ - space /*< the skip-parser >*/ - ); - if (first != last) // fail if we did not get a full match - return false; - return r; - } - //] -} - -//////////////////////////////////////////////////////////////////////////// -// Main program -//////////////////////////////////////////////////////////////////////////// -int -main() -{ - std::cout << "/////////////////////////////////////////////////////////\n\n"; - std::cout << "\t\tA comma separated list parser for Spirit...\n\n"; - std::cout << "/////////////////////////////////////////////////////////\n\n"; - - std::cout << "Give me a comma separated list of numbers.\n"; - std::cout << "Type [q or Q] to quit\n\n"; - - std::string str; - while (getline(std::cin, str)) - { - if (str.empty() || str[0] == 'q' || str[0] == 'Q') - break; - - if (client::parse_numbers(str.begin(), str.end())) - { - std::cout << "-------------------------\n"; - std::cout << "Parsing succeeded\n"; - std::cout << str << " Parses OK: " << std::endl; - } - else - { - std::cout << "-------------------------\n"; - std::cout << "Parsing failed\n"; - std::cout << "-------------------------\n"; - } - } - - std::cout << "Bye... :-) \n\n"; - return 0; -} - - Deleted: trunk/dsim/test/boost/spirit/roman_parser.cpp =================================================================== --- trunk/dsim/test/boost/spirit/roman_parser.cpp 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/roman_parser.cpp 2010-11-16 10:08:08 UTC (rev 156) @@ -1,186 +0,0 @@ -/*============================================================================= - Copyright (c) 2001-2010 Joel de Guzman - - Distributed under the Boost Software License, Version 1.0. (See accompanying - file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -=============================================================================*/ -/////////////////////////////////////////////////////////////////////////////// -// -// A Roman Numerals Parser (demonstrating the symbol table). This is -// discussed in the "Symbols" chapter in the Spirit User's Guide. -// -// [ JDG August 22, 2002 ] spirit1 -// [ JDG March 13, 2007 ] spirit2 -// -/////////////////////////////////////////////////////////////////////////////// - -#include <boost/config/warning_disable.hpp> -#include <boost/spirit/include/qi.hpp> -#include <boost/spirit/include/phoenix_operator.hpp> - -#include <iostream> -#include <string> - -namespace client -{ - namespace qi = boost::spirit::qi; - namespace ascii = boost::spirit::ascii; - - /////////////////////////////////////////////////////////////////////////////// - // Parse roman hundreds (100..900) numerals using the symbol table. - // Notice that the data associated with each slot is the parser's attribute - // (which is passed to attached semantic actions). - /////////////////////////////////////////////////////////////////////////////// - //[tutorial_roman_hundreds - struct hundreds_ : qi::symbols<char, unsigned> - { - hundreds_() - { - add - ("C" , 100) - ("CC" , 200) - ("CCC" , 300) - ("CD" , 400) - ("D" , 500) - ("DC" , 600) - ("DCC" , 700) - ("DCCC" , 800) - ("CM" , 900) - ; - } - - } hundreds; - //] - - /////////////////////////////////////////////////////////////////////////////// - // Parse roman tens (10..90) numerals using the symbol table. - /////////////////////////////////////////////////////////////////////////////// - //[tutorial_roman_tens - struct tens_ : qi::symbols<char, unsigned> - { - tens_() - { - add - ("X" , 10) - ("XX" , 20) - ("XXX" , 30) - ("XL" , 40) - ("L" , 50) - ("LX" , 60) - ("LXX" , 70) - ("LXXX" , 80) - ("XC" , 90) - ; - } - - } tens; - //] - - /////////////////////////////////////////////////////////////////////////////// - // Parse roman ones (1..9) numerals using the symbol table. - /////////////////////////////////////////////////////////////////////////////// - //[tutorial_roman_ones - struct ones_ : qi::symbols<char, unsigned> - { - ones_() - { - add - ("I" , 1) - ("II" , 2) - ("III" , 3) - ("IV" , 4) - ("V" , 5) - ("VI" , 6) - ("VII" , 7) - ("VIII" , 8) - ("IX" , 9) - ; - } - - } ones; - //] - - /////////////////////////////////////////////////////////////////////////////// - // roman (numerals) grammar - // - // Note the use of the || operator. The expression - // a || b reads match a or b and in sequence. Try - // defining the roman numerals grammar in YACC or - // PCCTS. Spirit rules! :-) - /////////////////////////////////////////////////////////////////////////////// - //[tutorial_roman_grammar - template <typename Iterator> - struct roman : qi::grammar<Iterator, unsigned()> - { - roman() : roman::base_type(start) - { - using qi::eps; - using qi::lit; - using qi::_val; - using qi::_1; - using ascii::char_; - - start = eps [_val = 0] >> - ( - +lit('M') [_val += 1000] - || hundreds [_val += _1] - || tens [_val += _1] - || ones [_val += _1] - ) - ; - } - - qi::rule<Iterator, unsigned()> start; - }; - //] -} - -/////////////////////////////////////////////////////////////////////////////// -// Main program -/////////////////////////////////////////////////////////////////////////////// -int -main() -{ - std::cout << "/////////////////////////////////////////////////////////\n\n"; - std::cout << "\t\tRoman Numerals Parser\n\n"; - std::cout << "/////////////////////////////////////////////////////////\n\n"; - std::cout << "Type a Roman Numeral ...or [q or Q] to quit\n\n"; - - typedef std::string::const_iterator iterator_type; - typedef client::roman<iterator_type> roman; - - roman roman_parser; // Our grammar - - std::string str; - unsigned result; - while (std::getline(std::cin, str)) - { - if (str.empty() || str[0] == 'q' || str[0] == 'Q') - break; - - std::string::const_iterator iter = str.begin(); - std::string::const_iterator end = str.end(); - //[tutorial_roman_grammar_parse - bool r = parse(iter, end, roman_parser, result); - - if (r && iter == end) - { - std::cout << "-------------------------\n"; - std::cout << "Parsing succeeded\n"; - std::cout << "result = " << result << std::endl; - std::cout << "-------------------------\n"; - } - else - { - std::string rest(iter, end); - std::cout << "-------------------------\n"; - std::cout << "Parsing failed\n"; - std::cout << "stopped at: \": " << rest << "\"\n"; - std::cout << "-------------------------\n"; - } - //] - } - - std::cout << "Bye... :-) \n\n"; - return 0; -} Deleted: trunk/dsim/test/boost/spirit/stream_iterator_parser.cpp =================================================================== --- trunk/dsim/test/boost/spirit/stream_iterator_parser.cpp 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/stream_iterator_parser.cpp 2010-11-16 10:08:08 UTC (rev 156) @@ -1,91 +0,0 @@ -// Copyright (c) 2010 Peter Schueller -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#include <vector> -#include <istream> -#include <sstream> -#include <iostream> -#include <fstream> -#include <boost/spirit/include/qi.hpp> -#include <boost/spirit/include/support_multi_pass.hpp> - -namespace qi = boost::spirit::qi; -namespace ascii = boost::spirit::ascii; - - -//////////////////////////////////////////////////////////////////////////// -// Parser -//////////////////////////////////////////////////////////////////////////// -template <typename iterator_t> -bool parse(iterator_t& iStr, iterator_t& iStrEnd, - std::vector<double>& output) { - - // Parse list of doubles from input stream - bool r = qi::phrase_parse( - iStr, iStrEnd, // Iterators - *(qi::double_ >> ';'), // Recognize list of doubles - ascii::space | '#' >> *(ascii::char_ - qi::eol) >> qi::eol, // Skip comment - output); // Store double into this object - - // Return result of parsing - return r; - -} - -//////////////////////////////////////////////////////////////////////////// -// Main program -//////////////////////////////////////////////////////////////////////////// -int main (int argc, char* argv[]) { - - std::string lFilename("good_input.csv"); - std::ifstream File; - - // Read the command-line parameters - if (argc >= 1 && argv[1] != NULL) { - lFilename = argv[1]; - File.open (argv[1],std::ios_base::in); - } else { - // Default File to be parsed - File.open ("good_input.csv",std::ios_base::in); - } - - // Check the File existence - if (!File) { - std::cerr << "Unknown file named" << lFilename << std::endl; - return 1; - } - - // Iterate over stream input - typedef std::istreambuf_iterator<char> base_iterator_type; - base_iterator_type in_begin(File.rdbuf()); - - // Convert input iterator to forward iterator, usable by spirit parser - typedef boost::spirit::multi_pass<base_iterator_type>forward_iterator_type; - forward_iterator_type fwd_begin = - boost::spirit::make_default_multi_pass(in_begin); - forward_iterator_type fwd_end; - - // Prepare output - std::vector<double> output; - - try { - bool r = parse(fwd_begin, fwd_end, output); - // Error detection - if( !r || fwd_begin != fwd_end ) { - throw std::runtime_error("parse error in "+lFilename); - } else { - std::cout << "--------------------------------------------\n"; - std::cout << "Parsing of the file " << lFilename <<" succeeded\n"; - std::cout << "Got: "; - for (unsigned int i = 0; i < output.size(); i++) { - std::cout << output[i] << " "; - } - std::cout << "\n--------------------------------------------\n"; - } - } catch(const std::exception& e) { - std::cerr << "Exception: " << e.what() << std::endl; - } - return 0; -} - Deleted: trunk/dsim/test/boost/spirit/sum_parser.cpp =================================================================== --- trunk/dsim/test/boost/spirit/sum_parser.cpp 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/sum_parser.cpp 2010-11-16 10:08:08 UTC (rev 156) @@ -1,104 +0,0 @@ -/*============================================================================= - Copyright (c) 2002-2010 Joel de Guzman - - Distributed under the Boost Software License, Version 1.0. (See accompanying - file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -=============================================================================*/ -/////////////////////////////////////////////////////////////////////////////// -// -// A parser for summing a comma-separated list of numbers using phoenix. -// -// [ JDG June 28, 2002 ] spirit1 -// [ JDG March 24, 2007 ] spirit2 -// -/////////////////////////////////////////////////////////////////////////////// - -#include <boost/config/warning_disable.hpp> -//[tutorial_adder_includes -#include <boost/spirit/include/qi.hpp> -#include <boost/spirit/include/phoenix_core.hpp> -#include <boost/spirit/include/phoenix_operator.hpp> -#include <iostream> -#include <string> -//] - -namespace client -{ - //[tutorial_adder_using - namespace qi = boost::spirit::qi; - namespace ascii = boost::spirit::ascii; - namespace phoenix = boost::phoenix; - - using qi::double_; - using qi::_1; - using ascii::space; - using phoenix::ref; - //] - - /////////////////////////////////////////////////////////////////////////// - // Our adder - /////////////////////////////////////////////////////////////////////////// - - //[tutorial_adder - template <typename Iterator> - bool adder(Iterator first, Iterator last, double& n) - { - bool r = qi::phrase_parse(first, last, - - // Begin grammar - ( - double_[ref(n) = _1] >> *(',' >> double_[ref(n) += _1]) - ) - , - // End grammar - - space); - - if (first != last) // fail if we did not get a full match - return false; - return r; - } - //] -} - -//////////////////////////////////////////////////////////////////////////// -// Main program -//////////////////////////////////////////////////////////////////////////// -int -main() -{ - std::cout << "/////////////////////////////////////////////////////////\n\n"; - std::cout << "\t\tA parser for summing a list of numbers...\n\n"; - std::cout << "/////////////////////////////////////////////////////////\n\n"; - - std::cout << "Give me a comma separated list of numbers.\n"; - std::cout << "The numbers are added using Phoenix.\n"; - std::cout << "Type [q or Q] to quit\n\n"; - - std::string str; - while (getline(std::cin, str)) - { - if (str.empty() || str[0] == 'q' || str[0] == 'Q') - break; - - double n; - if (client::adder(str.begin(), str.end(), n)) - { - std::cout << "-------------------------\n"; - std::cout << "Parsing succeeded\n"; - std::cout << str << " Parses OK: " << std::endl; - - std::cout << "sum = " << n; - std::cout << "\n-------------------------\n"; - } - else - { - std::cout << "-------------------------\n"; - std::cout << "Parsing failed\n"; - std::cout << "-------------------------\n"; - } - } - - std::cout << "Bye... :-) \n\n"; - return 0; -} Modified: trunk/dsim/test/boost/spirit/world_schedule.csv =================================================================== --- trunk/dsim/test/boost/spirit/world_schedule.csv 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spirit/world_schedule.csv 2010-11-16 10:08:08 UTC (rev 156) @@ -3,9 +3,9 @@ // ElapsedTime; LegCabins; // LegCabins: CabinCode; Capacity; // Segments: Specific; -BA; 9; 2007-04-20; 2007-06-30; 0000011; LHR; BKK; 22:00; 15:15; 11:15; F; 5; J; 12; W; 20; Y; 300; BKK; SYD; 18:10; 06:05; 08:55; F; 5; J; 12; W; 20; Y; 300; 0; F; FA; J; JCDI; W; WT; Y; YBHKMLSQ; -BA; 9; 2007-04-20; 2007-06-30; 1111100; LHR; BKK; 22:00; 15:15; 11:15; F; 5; J; 12; W; 20; Y; 300; BKK; SYD; 18:10; 06:05; 08:55; F; 5; J; 12; W; 20; Y; 300; 1; LHR; BKK; F; FA; J; JCDI; W; WT; Y; YBHKMLSQ; BKK; SYD; F; FA; J; JCDI; W; WT; Y; YBHKMLSQ; LHR; SYD; F; FA; J; JCDI; W; WT; Y; YBHKMLSQ; -BA; 117; 2007-04-20; 3000-06-30; 1111111; LHR; JFK; 08:20; 11:00; 07:40; F; 5; J; 12; W; 20; Y; 300; 0; F; FA; J; JCDI; W; WT; Y; YBHKM; +BA; 9; 2007-04-20; 2007-06-30; 0000011; LHR; BKK; 22:00; 15:15 / +1; 11:15; F; 5; J; 12; W; 20; Y; 300; BKK; SYD; 18:10 / +1; 06:05 / +2; 08:55; F; 5; J; 12; W; 20; Y; 300; 0; F; FA; J; JCDI; W; WT; Y; YBHKMLSQ; +BA; 9; 2007-04-20; 2007-06-30; 1111100; LHR; BKK; 22:00; 15:15 / +1; 11:15; F; 5; J; 12; W; 20; Y; 300; BKK; SYD; 18:10 / +1; 06:05 / +2; 08:55; F; 5; J; 12; W; 20; Y; 300; 1; LHR; BKK; F; FA; J; JCDI; W; WT; Y; YBHKMLSQ; BKK; SYD; F; FA; J; JCDI; W; WT; Y; YBHKMLSQ; LHR; SYD; F; FA; J; JCDI; W; WT; Y; YBHKMLSQ; +BA; 117; 2007-04-20; 2007-06-30; 1111111; LHR; JFK; 08:20; 11:00; 07:40; F; 5; J; 12; W; 20; Y; 300; 0; F; FA; J; JCDI; W; WT; Y; YBHKM; BA; 175; 2007-04-20; 2007-06-30; 1111111; LHR; JFK; 10:55; 13:35; 07:40; F; 5; J; 12; W; 20; Y; 300; 0; F; FA; J; JCDI; W; WT; Y; YBHKMRL; BA; 179; 2007-04-20; 2007-06-30; 1111111; LHR; JFK; 18:05; 20:45; 07:40; F; 5; J; 12; W; 20; Y; 300; 0; F; FA; J; JCDI; W; WT; Y; YBHKMRVNELSQO; BA; 207; 2007-04-20; 2007-06-30; 1111111; LHR; MIA; 09:40; 14:25; 09:45; F; 5; J; 12; W; 20; Y; 300; 0; F; FA; J; JCDI; W; WT; Y; YBHKMRVNELSQO; Modified: trunk/dsim/test/boost/spiritQi/schedule_parser.cpp =================================================================== --- trunk/dsim/test/boost/spiritQi/schedule_parser.cpp 2010-11-10 20:15:47 UTC (rev 155) +++ trunk/dsim/test/boost/spiritQi/schedule_parser.cpp 2010-11-16 10:08:08 UTC (rev 156) @@ -20,52 +20,695 @@ typedef std::string::const_iterator iterator_t; + +/** LegCabin-Details. */ +struct Cabin_T { + // Attributes + std::string _cabinCode; + double _capacity; + + void display() const { + std::cout << " " << _cabinCode << " " << _capacity << ", "; + } +}; + +/** List of Cabin-Detail strucutres. */ +typedef std::vector<Cabin_T> CabinList_T; + +/** Leg. */ +struct Leg_T { + // Attributes + std::string _boardPoint; + boost::posix_time::time_duration _boardTime; + boost::gregorian::date_duration _boardDateOffSet; + std::string _offPoint; + boost::posix_time::time_duration _offTime; + boost::gregorian::date_duration _offDateOffSet; + boost::posix_time::time_duration _elapsed; + CabinList_T _cabinList; + + /** Constructor. */ + Leg_T () : _boardDateOffSet (0), _offDateOffSet (0) {} + + void display() const { + std::cout << " " << _boardPoint << " / " + << boost::posix_time::to_simple_string (_boardTime) + << " -- " << _offPoint << " / " + << boost::posix_time::to_simple_string (_offTime) + << " --> " << boost::posix_time::to_simple_string (_elapsed) + << std::endl; + for (CabinList_T::const_iterator itCabin = _cabinList.begin(); + itCabin != _cabinList.end(); itCabin++) { + const Cabin_T& lCabin = *itCabin; + lCabin.display(); + } + std::cout << std::endl; + } +}; + +/** List of Leg strucutres. */ +typedef std::vector<Leg_T> LegList_T; + +/** SegmentCabin-Details. */ +struct SegmentCabin_T { + // Attributes + std::string _cabinCode; + std::string _classes; + + void display() const { + std::cout << " " << _cabinCode << " " << _classes << ", "; + } +}; + +/** List of SegmentCabin-Detail strucutres. */ +typedef std::vector<SegmentCabin_T> SegmentCabinList_T; + +/** Segment. */ +struct Segment_T { + // Attributes + std::string _boardPoint; + boost::posix_time::time_duration _boardTime; + boost::gregorian::date_duration _boardDateOffSet; + std::string _offPoint; + boost::posix_time::time_duration _offTime; + boost::gregorian::date_duration _offDateOffSet; + boost::posix_time::time_duration _elapsed; + SegmentCabinList_T _cabinList; + + /** Constructor. */ + Segment_T () : _boardDateOffSet (0), _offDateOffSet (0) {} + + void display() const { + std::cout << " " << _boardPoint << " / " + << boost::posix_time::to_simple_string (_boardTime) + << " -- " << _offPoint << " / " + << boost::posix_time::to_simple_string (_offTime) + << " --> " << boost::posix_time::to_simple_string (_elapsed) + << std::endl; + for (SegmentCabinList_T::const_iterator itCabin = _cabinList.begin(); + itCabin != _cabinList.end(); itCabin++) { + const SegmentCabin_T& lCabin = *itCabin; + lCabin.display(); + } + std::cout << std::endl; + } +}; + +/** List of Segment strucutres. */ +typedef std::vector<Segment_T> SegmentList_T; + /** Flight-Period. */ struct FlightPeriod_T { + // Attributes std::string _airlineCode; unsigned int _flightNumber; boost::gregorian::date _dateRangeStart; boost::gregorian::date _dateRangeEnd; std::string _dow; - std::string _cabinCode; + LegList_T _legList; + SegmentList_T _segmentList; + + /** Constructor. */ + FlightPeriod_T () : _legAlreadyDefined (false), _itSeconds (0) {} + + /** Set the date from the staging details. */ + boost::gregorian::date getDate() const { + return boost::gregorian::date (_itYear, _itMonth, _itDay); + } + + /** Set the time from the staging details. */ + boost::posix_time::time_duration getTime() const { + return boost::posix_time::hours (_itHours) + + boost::posix_time::minutes (_itMinutes) + + boost::posix_time::seconds (_itSeconds); + } + + void display() const { + std::cout << _airlineCode << _flightNumber + << ", " << boost::gregorian::to_simple_string (_dateRangeStart) + << " - " << boost::gregorian::to_simple_string (_dateRangeEnd) + << " - " << _dow + << std::endl; + + for (LegList_T::const_iterator itLeg = _legList.begin(); + itLeg != _legList.end(); itLeg++) { + const Leg_T& lLeg = *itLeg; + lLeg.display(); + } + + for (SegmentList_T::const_iterator itSegment = _segmentList.begin(); + itSegment != _segmentList.end(); itSegment++) { + const Segment_T& lSegment = *itSegment; + lSegment.display(); + } + + //std::cout << "[Debug] - Staging Leg: "; + //_itLeg.display(); + //std::cout << "[Debug] - Staging Cabin: "; + //_itCabin.display(); + //std::cout << "[Debug] - Staging Segment: "; + //_itSegment.display(); + } + + /** Add the given airport to the internal lists (if not already existing). */ + void addAirport (const std::string& iAirport) { + std::set<std::string>::const_iterator itAirport = + _airportList.find (iAirport); + if (itAirport == _airportList.end()) { + // Add the airport code to the airport set + const bool insertSuccessful = _airportList.insert (iAirport).second; + + if (insertSuccessful == false) { + // TODO: throw an exception + } + // Add the airport code to the airport vector + _airportOrderedList.push_back (iAirport); + } + } + + /** Build the routing (segments). */ + void buildSegments () { + // The list of airports encompasses all the airports on which + // the flight takes off or lands. Moreover, that list is + // time-ordered: the first airport is the initial departure of + // the flight, and the last airport is the eventual point of + // rest of the flight. + // Be l the size of the ordered list of airports. + // We want to generate all the segment combinations from the legs + // and, hence, from all the possible (time-ordered) airport pairs. + // Thus, we both iterator on i=0...l-1 and j=i+1...l + assert (_airportOrderedList.size() >= 2); + + _segmentList.clear(); + for (std::vector<std::string>::const_iterator itAirport_i = + _airportOrderedList.begin(); + itAirport_i != _airportOrderedList.end()-1; ++itAirport_i) { + for (std::vector<std::string>::const_iterator itAirport_j = + itAirport_i + 1; + itAirport_j != _airportOrderedList.end(); ++itAirport_j) { + Segment_T lSegment; + lSegment._boardPoint = *itAirport_i; + lSegment._offPoint = *itAirport_j; + + _segmentList.push_back (lSegment); + } + } + + // Clear the lists of airports, so that it is ready for the next flight + _airportList.clear(); + _airportOrderedList.clear(); + } + + /** Add, to the Segment whose key corresponds to the + given (board point, off point) pair, the specific segment cabin + details (mainly, the list of the class codes). + <br>Note that the Segment structure is retrieved from the internal + list, already filled by a previous step (the buildSegments() + method). */ + void addSegmentCabin (const Segment_T& iSegment, + const SegmentCabin_T& iCabin) { + // Retrieve the Segment structure corresponding to the (board, off) point + // pair. + SegmentList_T::iterator itSegment = _segmentList.begin(); + for ( ; itSegment != _segmentList.end(); ++itSegment) { + const Segment_T& lSegment = *itSegment; + + const std::string& lBoardPoint = iSegment._boardPoint; + const std::string& lOffPoint = iSegment._offPoint; + if (lSegment._boardPoint == lBoardPoint + && lSegment._offPoint == lOffPoint) { + break; + } + } + + // If the segment key (airport pair) given in the schedule input file + // does not correspond to the leg (board, off) points, throw an exception + // so that the user knows the schedule input file is corrupted. + if (itSegment == _segmentList.end()) { + std::cerr << "Within the schedule input file, there is a flight for which the airports of segments and those of the legs do not correspond."; + throw std::exception(); + } + + // Add the Cabin structure to the Segment Cabin structure. + assert (itSegment != _segmentList.end()); + Segment_T& lSegment = *itSegment; + lSegment._cabinList.push_back (iCabin); + } + + /** Add, to all the Segment, the general segment cabin details + (mainly, the list of the class codes). + <br>Note that the Segment structures are stored within the internal + list, already filled by a previous step (the buildSegments() + method). */ + void addSegmentCabin (const SegmentCabin_T& iCabin) { + // Iterate on all the Segment (as they get the same cabin definitions) + for (SegmentList_T::iterator itSegment = _segmentList.begin(); + itSegment != _segmentList.end(); ++itSegment) { + Segment_T& lSegment = *itSegment; + lSegment._cabinList.push_back (iCabin); + } + } + + /** Staging Leg (resp. Cabin) structure, gathering the result of the iteration + on one leg (resp. cabin). */ + bool _legAlreadyDefined; + Leg_T _itLeg; + Cabin_T _itCabin; + + /** Staging Date. */ + unsigned int _itYear; + unsigned int _itMonth; + unsigned int _itDay; + + /** Staging Time. */ + long _itHours; + long _itMinutes; + long _itSeconds; + int _dateOffSet; + + /** Staging Airport List (helper to derive the list of Segment + structures). */ + std::set<std::string> _airportList; + std::vector<std::string> _airportOrderedList; + + /** Staging Segment-related attributes. */ + bool _areSegmentDefinitionsSpecific; + Segment_T _itSegment; + SegmentCabin_T _itSegmentCabin; + }; +/////////////////////////////////////////////////////////////////////////////// +// +// Semantic actions +// +/////////////////////////////////////////////////////////////////////////////// + /** Store the parsed airline code. */ template <typename FLIGHT_PERIOD> struct store_airline_code { store_airline_code (FLIGHT_PERIOD& ioFlightPeriod) : _flightPeriod (ioFlightPeriod) {} - void operator() (iterator_t iStr, iterator_t iStrEnd) const { - std::string lAirlineCode (iStr, iStrEnd); + void operator() (std::vector<char> iChar, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + std::string lAirlineCode (iChar.begin(), iChar.end()); _flightPeriod._airlineCode = lAirlineCode; // std::cout << "Airline code: " << lAirlineCode << std::endl; + + // As that's the beginning of a new flight, the list of legs must be reset + _flightPeriod._legList.clear(); } FLIGHT_PERIOD& _flightPeriod; }; +/** Store the parsed flight number. */ +template <typename FLIGHT_PERIOD> +struct store_flight_number { + store_flight_number (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (unsigned int iNumber, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + _flightPeriod._flightNumber = iNumber; + //std::cout << "Flight number: " << iNumber << std::endl; + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the start of the date range. */ +template <typename FLIGHT_PERIOD> +struct store_date_range_start { + store_date_range_start (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + _flightPeriod._dateRangeStart = _flightPeriod.getDate(); + //std::cout << "Date Range Start: " + // << _flightPeriod._dateRangeStart << std::endl; + + // Reset the number of seconds + _flightPeriod._itSeconds = 0; + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the end of the date range. */ +template <typename FLIGHT_PERIOD> +struct store_date_range_end { + store_date_range_end (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + _flightPeriod._dateRangeEnd = _flightPeriod.getDate(); + //std::cout << "Date Range End: " + // << _flightPeriod._dateRangeEnd << std::endl; + + // Reset the number of seconds + _flightPeriod._itSeconds = 0; + } + + FlightPeriod_T& _flightPeriod; +}; + +/** Store the DOW (day of the Week). */ +template <typename FLIGHT_PERIOD> +struct store_dow { + store_dow (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (std::vector<char> iChar, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + std::string lDow (iChar.begin(), iChar.end()); + _flightPeriod._dow = lDow; + //std::cout << "DOW: " << lDow << std::endl; + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the parsed board point. */ +template <typename FLIGHT_PERIOD> +struct store_board_point { + store_board_point (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (std::vector<char> iChar, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + std::string lBoardPoint (iChar.begin(), iChar.end()); + //std::cout << "Board point: " << lBoardPoint << std::endl; + + // If a leg has already been parsed, add it to the FlightPeriod + if (_flightPeriod._legAlreadyDefined == true) { + _flightPeriod._legList.push_back (_flightPeriod._itLeg); + } else { + _flightPeriod._legAlreadyDefined = true; + } + + // Set the (new) board point + _flightPeriod._itLeg._boardPoint = lBoardPoint; + + // As that's the beginning of a new leg, the list of cabins must be reset + _flightPeriod._itLeg._cabinList.clear(); + + // Add the airport code if it is not already stored in the airport lists + _flightPeriod.addAirport (lBoardPoint); + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the parsed off point. */ +template <typename FLIGHT_PERIOD> +struct store_off_point { + store_off_point (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (std::vector<char> iChar, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + std::string lOffPoint (iChar.begin(), iChar.end()); + _flightPeriod._itLeg._offPoint = lOffPoint; + //std::cout << "Off point: " << lOffPoint << std::endl; + + // Add the airport code if it is not already stored in the airport lists + _flightPeriod.addAirport (lOffPoint); + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the board time. */ +template <typename FLIGHT_PERIOD> +struct store_board_time { + store_board_time (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + _flightPeriod._itLeg._boardTime = _flightPeriod.getTime(); + + //std::cout << "Board time: " + //<< _flightPeriod._itLeg._boardTime << std::endl; + + // Reset the number of seconds + _flightPeriod._itSeconds = 0; + + // Reset the date off-set + _flightPeriod._dateOffSet = 0; + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the off time. */ +template <typename FLIGHT_PERIOD> +struct store_off_time { + store_off_time (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + _flightPeriod._itLeg._offTime = _flightPeriod.getTime(); + + //std::cout << "Off time: " + // << _flightPeriod._itLeg._offTime << std::endl; + + // Reset the number of seconds + _flightPeriod._itSeconds = 0; + + // As the board date off set is optional, it can be set only afterwards, + // based on the staging date off-set value (_flightPeriod._dateOffSet). + const boost::gregorian::date_duration lDateOffSet (_flightPeriod._dateOffSet); + _flightPeriod._itLeg._boardDateOffSet = lDateOffSet; + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the elapsed time. */ +template <typename FLIGHT_PERIOD> +struct store_elapsed_time { + store_elapsed_time (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + + _flightPeriod._itLeg._elapsed = _flightPeriod.getTime(); + + //std::cout << "Elapsed time: " + // << _flightPeriod._itLeg._elapsed << std::endl; + + // Reset the number of seconds + _flightPeriod._itSeconds = 0; + + // As the board date off set is optional, it can be set only afterwards, + // based on the staging date off-set value (_flightPeriod._dateOffSet). + const boost::gregorian::date_duration lDateOffSet (_flightPeriod._dateOffSet); + _flightPeriod._itLeg._offDateOffSet = lDateOffSet; + } + + FLIGHT_PERIOD& _flightPeriod; +}; + /** Store the parsed cabin code. */ template <typename FLIGHT_PERIOD> struct store_cabin_code { store_cabin_code (FLIGHT_PERIOD& ioFlightPeriod) : _flightPeriod (ioFlightPeriod) {} - void operator() (char iChar, boost::spirit::qi::unused_type, + void operator() (char iChar, + boost::spirit::qi::unused_type, boost::spirit::qi::unused_type) const { - _flightPeriod._cabinCode = iChar; - // std::cout << "Cabin code: " << lCabinCode << std::endl; + _flightPeriod._itCabin._cabinCode = iChar; + //std::cout << "Cabin code: " << _flightPeriod._itCabin._cabinCode << std::endl; } FLIGHT_PERIOD& _flightPeriod; }; + +/** Store the parsed capacity. */ +template <typename FLIGHT_PERIOD> +struct store_capacity { + store_capacity (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (double iReal, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + _flightPeriod._itCabin._capacity = iReal; + //std::cout << "Capacity: " << iReal << std::endl; + + // The capacity is the last (according to arrival order) detail + // of the cabin. Hence, when a capacity is parsed, it means that + // the full cabin details have already been parsed as well: the + // cabin can thus be added to the leg. + _flightPeriod._itLeg._cabinList.push_back (_flightPeriod._itCabin); + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store whether or not all the segments are the same. */ +template <typename FLIGHT_PERIOD> +struct store_segment_specificity { + store_segment_specificity (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + void operator() (char iChar, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + if (iChar == '0') { + _flightPeriod._areSegmentDefinitionsSpecific = false; + } else { + _flightPeriod._areSegmentDefinitionsSpecific = true; + } + + // Do a few sanity checks: the two lists should get exactly the same + // content (in terms of airport codes). The only difference is that one + // is a STL set, and the other a STL vector. + assert (_flightPeriod._airportList.size() + == _flightPeriod._airportOrderedList.size()); + assert (_flightPeriod._airportList.size() >= 2); + + // Since all the legs have now been parsed, we get all the airports + // and the segments may be built. + _flightPeriod.buildSegments(); + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the board point of the segment. */ +template <typename FLIGHT_PERIOD> +struct store_segment_board_point { + store_segment_board_point (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + void operator() (std::vector<char> iChar, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + std::string lBoardPoint (iChar.begin(), iChar.end()); + _flightPeriod._itSegment._boardPoint = lBoardPoint; + //std::cout << "Board point: " << lBoardPoint << std::endl; + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the off point of the segment. */ +template <typename FLIGHT_PERIOD> +struct store_segment_off_point { + store_segment_off_point (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + void operator() (std::vector<char> iChar, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + std::string lOffPoint (iChar.begin(), iChar.end()); + _flightPeriod._itSegment._offPoint = lOffPoint; + //std::cout << "Off point: " << lOffPoint << std::endl; + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the cabin code of the segment. */ +template <typename FLIGHT_PERIOD> +struct store_segment_cabin_code { + store_segment_cabin_code (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + void operator() (char iChar, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + _flightPeriod._itSegmentCabin._cabinCode = iChar; + //std::cout << "Cabin code: " << iChar << std::endl; + } + + FLIGHT_PERIOD& _flightPeriod; +}; + +/** Store the classes of the segment-cabin. */ +template <typename FLIGHT_PERIOD> +struct store_classes { + store_classes (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + void operator() (std::vector<char> iChar, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + std::string lClasses (iChar.begin(), iChar.end()); + _flightPeriod._itSegmentCabin._classes = lClasses; + //std::cout << "Classes: " << lClasses << std::endl; + + // The list of classes is the last (according to the arrival order + // within the schedule input file) detail of the segment cabin. Hence, + // when a list of classes is parsed, it means that the full segment + // cabin details have already been parsed as well: the segment cabin + // can thus be added to the segment. + if (_flightPeriod._areSegmentDefinitionsSpecific == true) { + _flightPeriod.addSegmentCabin (_flightPeriod._itSegment, + _flightPeriod._itSegmentCabin); + } else { + _flightPeriod.addSegmentCabin (_flightPeriod._itSegmentCabin); + } + } + + FLIGHT_PERIOD& _flightPeriod; +}; +/** Mark the end of the flight-period parsing. */ +template <typename FLIGHT_PERIOD> +struct do_end_flight { + do_end_flight (FLIGHT_PERIOD& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type, + boost::spirit::qi::unused_type) const { + //std::cout << "End of Flight-Period " << std::endl; + assert (_flightPeriod._legAlreadyDefined == true); + _flightPeriod._legList.push_back (_flightPeriod._itLeg); + + // Display the result + _flightPeriod.display(); + + // The lists of legs and cabins must be reset + _flightPeriod._legAlreadyDefined = false; + _flightPeriod._itLeg._cabinList.clear(); + + } + + FLIGHT_PERIOD& _flightPeriod; +}; + // /////////// Utilities ///////////// /** 1-digit-integer parser */ -boost::spirit::qi::uint_parser<int, 10, 1, 1> int1_p; +boost::spirit::qi::int_parser<unsigned int, 10, 1, 1> int1_p; /** 2-digit-integer parser */ boost::spirit::qi::uint_parser<int, 10, 2, 2> ... [truncated message content] |