[Opentrep-svn] SF.net SVN: opentrep:[120] trunk/opentrep
Status: Beta
Brought to you by:
denis_arnaud
From: <den...@us...> - 2009-07-12 13:36:46
|
Revision: 120 http://opentrep.svn.sourceforge.net/opentrep/?rev=120&view=rev Author: denis_arnaud Date: 2009-07-12 13:36:35 +0000 (Sun, 12 Jul 2009) Log Message: ----------- [Test] Added some tests on parsers. Modified Paths: -------------- trunk/opentrep/configure.ac trunk/opentrep/test/Makefile.am Added Paths: ----------- trunk/opentrep/test/parsers/ trunk/opentrep/test/parsers/Makefile.am trunk/opentrep/test/parsers/full_calculator.cpp trunk/opentrep/test/parsers/levenshtein.cpp trunk/opentrep/test/parsers/parameter_parser.cpp trunk/opentrep/test/parsers/schedule_parser.cpp trunk/opentrep/test/parsers/test_full_calculator.sh trunk/opentrep/test/parsers/test_parameter_parser.sh trunk/opentrep/test/parsers/test_schedule_parser.sh trunk/opentrep/test/parsers/world_schedule.csv Modified: trunk/opentrep/configure.ac =================================================================== --- trunk/opentrep/configure.ac 2009-07-12 12:59:01 UTC (rev 119) +++ trunk/opentrep/configure.ac 2009-07-12 13:36:35 UTC (rev 120) @@ -233,6 +233,7 @@ doc/sourceforge/howto_release_opentrep.html po/Makefile.in test/com/Makefile + test/parsers/Makefile test/Makefile win32/Makefile) AC_OUTPUT Modified: trunk/opentrep/test/Makefile.am =================================================================== --- trunk/opentrep/test/Makefile.am 2009-07-12 12:59:01 UTC (rev 119) +++ trunk/opentrep/test/Makefile.am 2009-07-12 13:36:35 UTC (rev 120) @@ -4,7 +4,7 @@ MAINTAINERCLEANFILES = Makefile.in ## -SUBDIRS = com +SUBDIRS = com parsers ## check_PROGRAMS = IndexBuildingTestSuite Property changes on: trunk/opentrep/test/parsers ___________________________________________________________________ Added: svn:ignore + .libs .deps Makefile Makefile.in parameter_parser* full_calculator* schedule_parser* levenshtein* Added: trunk/opentrep/test/parsers/Makefile.am =================================================================== --- trunk/opentrep/test/parsers/Makefile.am (rev 0) +++ trunk/opentrep/test/parsers/Makefile.am 2009-07-12 13:36:35 UTC (rev 120) @@ -0,0 +1,24 @@ +## command sub-directory +include $(top_srcdir)/Makefile.common + +MAINTAINERCLEANFILES = Makefile.in + +check_PROGRAMS = full_calculator parameter_parser schedule_parser levenshtein + +full_calculator_SOURCES = full_calculator.cpp +full_calculator_CXXFLAGS = $(BOOST_CFLAGS) +full_calculator_LDADD = $(BOOST_LIB) + +parameter_parser_SOURCES = parameter_parser.cpp +parameter_parser_CXXFLAGS = $(BOOST_CFLAGS) +parameter_parser_LDADD = $(BOOST_LIB) + +schedule_parser_SOURCES = schedule_parser.cpp +schedule_parser_CXXFLAGS = $(BOOST_CFLAGS) +schedule_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 Added: trunk/opentrep/test/parsers/full_calculator.cpp =================================================================== --- trunk/opentrep/test/parsers/full_calculator.cpp (rev 0) +++ trunk/opentrep/test/parsers/full_calculator.cpp 2009-07-12 13:36:35 UTC (rev 120) @@ -0,0 +1,131 @@ +/*============================================================================= + Copyright (c) 2002-2003 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to 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) + =============================================================================*/ +//////////////////////////////////////////////////////////////////////////// +// +// Full calculator example demonstrating Phoenix +// This is discussed in the "Closures" chapter in the Spirit User's Guide. +// +// [ JDG 6/29/2002 ] +// +//////////////////////////////////////////////////////////////////////////// +#include <boost/spirit/core.hpp> +#include <boost/spirit/attribute.hpp> +#include <iostream> +#include <string> + +//////////////////////////////////////////////////////////////////////////// +using namespace std; +using namespace boost::spirit; +using namespace phoenix; + +//////////////////////////////////////////////////////////////////////////// +// +// Our calculator grammar using phoenix to do the semantics +// +// Note: The top rule propagates the expression result (value) upwards +// to the calculator grammar self.val closure member which is +// then visible outside the grammar (i.e. since self.val is the +// member1 of the closure, it becomes the attribute passed by +// the calculator to an attached semantic action. See the +// driver code that uses the calculator below). +// +//////////////////////////////////////////////////////////////////////////// +struct calc_closure : boost::spirit::closure<calc_closure, double> +{ + member1 val; +}; + +struct calculator : public grammar<calculator, calc_closure::context_t> +{ + template <typename ScannerT> + struct definition + { + definition(calculator const& self) + { + top = expression[self.val = arg1]; + + expression + = term[expression.val = arg1] + >> *( ('+' >> term[expression.val += arg1]) + | ('+' >> term[expression.val -= arg1]) + | ('-' >> term[expression.val -= arg1]) + ) + ; + + term + = factor[term.val = arg1] + >> *( ('*' >> factor[term.val *= arg1]) + | ('/' >> factor[term.val /= arg1]) + ) + ; + + factor + = ureal_p[factor.val = arg1] + | '(' >> expression[factor.val = arg1] >> ')' + | ('-' >> factor[factor.val = -arg1]) + | ('+' >> factor[factor.val = arg1]) + ; + } + + typedef rule<ScannerT, calc_closure::context_t> rule_t; + rule_t expression, term, factor; + rule<ScannerT> top; + + rule<ScannerT> const& + start() const { return top; } + }; +}; + +//////////////////////////////////////////////////////////////////////////// +// +// Main program +// +//////////////////////////////////////////////////////////////////////////// +int +main() +{ + cout << "/////////////////////////////////////////////////////////\n\n"; + cout << "\t\tExpression parser using Phoenix...\n\n"; + cout << "/////////////////////////////////////////////////////////\n\n"; + cout << "Type an expression...or [q or Q] to quit\n\n"; + + calculator calc; // Our parser + + string str; + while (getline(cin, str)) + { + if (str.empty() || str[0] == 'q' || str[0] == 'Q') + break; + + double n = 0; + parse_info<> info = parse(str.c_str(), calc[var(n) = arg1], space_p); + + // calc[var(n) = arg1] invokes the calculator and extracts + // the result of the computation. See calculator grammar + // note above. + + if (info.full) + { + cout << "-------------------------\n"; + cout << "Parsing succeeded\n"; + cout << "result = " << n << endl; + cout << "-------------------------\n"; + } + else + { + cout << "-------------------------\n"; + cout << "Parsing failed\n"; + cout << "stopped at: \": " << info.stop << "\"\n"; + cout << "-------------------------\n"; + } + } + + cout << "Bye... :-) \n\n"; + return 0; +} Added: trunk/opentrep/test/parsers/levenshtein.cpp =================================================================== --- trunk/opentrep/test/parsers/levenshtein.cpp (rev 0) +++ trunk/opentrep/test/parsers/levenshtein.cpp 2009-07-12 13:36:35 UTC (rev 120) @@ -0,0 +1,131 @@ +// Levenshtein Distance Algorithm: C++ Implementation by Anders Sewerin Johansen +// STL +#include <iostream> +#include <string> +#include <vector> + +// ////////////////////////////////////////////////////////////////// +int getLevenshteinDistance (const std::string& source, + const std::string& target) { + + // Step 1 + + const int n = source.length(); + const int m = target.length(); + if (n == 0) { + return m; + } + if (m == 0) { + return n; + } + + // Definition of Matrix Type + typedef std::vector< std::vector<int> > Matrix_T; + + Matrix_T matrix (n+1); + + // Size the vectors in the 2.nd dimension. Unfortunately C++ doesn't + // allow for allocation on declaration of 2.nd dimension of vec of vec + + for (int i = 0; i <= n; i++) { + matrix[i].resize(m+1); + } + + // Step 2 + + for (int i = 0; i <= n; i++) { + matrix[i][0]=i; + } + + for (int j = 0; j <= m; j++) { + matrix[0][j]=j; + } + + // Step 3 + + for (int i = 1; i <= n; i++) { + + const char s_i = source[i-1]; + + // Step 4 + + for (int j = 1; j <= m; j++) { + + const char t_j = target[j-1]; + + // Step 5 + + int cost; + if (s_i == t_j) { + cost = 0; + } + else { + cost = 1; + } + + // Step 6 + + const int above = matrix[i-1][j]; + const int left = matrix[i][j-1]; + const int diag = matrix[i-1][j-1]; + int cell = std::min ( above + 1, std::min (left + 1, diag + cost)); + + // Step 6A: Cover transposition, in addition to deletion, + // insertion and substitution. This step is taken from: + // Berghel, Hal ; Roach, David : "An Extension of Ukkonen's + // Enhanced Dynamic Programming ASM Algorithm" + // (http://www.acm.org/~hlb/publications/asm/asm.html) + + if (i>2 && j>2) { + int trans = matrix[i-2][j-2] + 1; + if (source[i-2] != t_j) { + trans++; + } + if (s_i != target[j-2]) { + trans++; + } + if (cell > trans) { + cell = trans; + } + } + + matrix[i][j] = cell; + } + } + + // Step 7 + + return matrix[n][m]; +} + + +// /////////// M A I N //////////////// +int main (int argc, char* argv[]) { + + const std::string lLax1Str = "los angeles"; + const std::string lLax2Str = "lso angeles"; + const std::string lRio1Str = "rio de janeiro"; + const std::string lRio2Str = "rio de janero"; + const std::string lRek1Str = "reikjavik"; + const std::string lRek2Str = "rekyavik"; + const std::string lSfoRio1Str = "san francisco rio de janeiro"; + const std::string lSfoRio2Str = "san francicso rio de janero"; + + std::cout << "Distance between '" << lLax1Str + << "' and '" << lLax2Str << "' is: " + << getLevenshteinDistance (lLax1Str, lLax2Str) << std::endl; + + std::cout << "Distance between '" << lRio1Str + << "' and '" << lRio2Str << "' is: " + << getLevenshteinDistance (lRio1Str, lRio2Str) << std::endl; + + std::cout << "Distance between '" << lRek1Str + << "' and '" << lRek2Str << "' is: " + << getLevenshteinDistance (lRek1Str, lRek2Str) << std::endl; + + std::cout << "Distance between '" << lSfoRio1Str + << "' and '" << lSfoRio2Str << "' is: " + << getLevenshteinDistance (lSfoRio1Str, lSfoRio2Str) << std::endl; + + return 0; +} Added: trunk/opentrep/test/parsers/parameter_parser.cpp =================================================================== --- trunk/opentrep/test/parsers/parameter_parser.cpp (rev 0) +++ trunk/opentrep/test/parsers/parameter_parser.cpp 2009-07-12 13:36:35 UTC (rev 120) @@ -0,0 +1,216 @@ +/*============================================================================= + Copyright (c) 2001-2003 Hartmut Kaiser + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to 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 show the usage of parser parameters. +// +// Parser parameters are used to pass some values from the outer parsing scope +// to the next inner scope. They can be imagined as the opposite to the return +// value paradigm, which returns some value from the inner to the next outer +// scope. See the "Closures" chapter in the User's Guide. + +#include <string> +#include <iostream> +#include <cassert> + +#if defined(_MSC_VER) /*&& !defined(__COMO__)*/ +#pragma warning(disable: 4244) +#pragma warning(disable: 4355) +#endif // defined(_MSC_VER) && !defined(__COMO__) + +#include <boost/spirit/core.hpp> +#include <boost/spirit/symbols/symbols.hpp> + +#include <boost/spirit/phoenix/tuples.hpp> +#include <boost/spirit/phoenix/tuple_helpers.hpp> +#include <boost/spirit/phoenix/primitives.hpp> +#include <boost/spirit/attribute/closure.hpp> + +/////////////////////////////////////////////////////////////////////////////// +// used namespaces +using namespace boost::spirit; +using namespace phoenix; +using namespace std; + +/////////////////////////////////////////////////////////////////////////////// +// Helper class for encapsulation of the type for the parsed variable names +class declaration_type +{ +public: + enum vartype { + vartype_unknown = 0, // unknown variable type + vartype_int = 1, // 'int' + vartype_real = 2 // 'real' + }; + + declaration_type() : type(vartype_unknown) + { + } + template <typename ItT> + declaration_type(ItT const &first, ItT const &last) + { + init(string(first, last-first-1)); + } + declaration_type(declaration_type const &type_) : type(type_.type) + { + } + declaration_type(string const &type_) : type(vartype_unknown) + { + init(type_); + } + + // access to the variable type + operator vartype const &() const { return type; } + operator string () + { + switch(type) { + default: + case vartype_unknown: break; + case vartype_int: return string("int"); + case vartype_real: return string("real"); + } + return string ("unknown"); + } + + void swap(declaration_type &s) { std::swap(type, s.type); } + +protected: + void init (string const &type_) + { + if (type_ == "int") + type = vartype_int; + else if (type_ == "real") + type = vartype_real; + else + type = vartype_unknown; + } + +private: + vartype type; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// used closure type +// +/////////////////////////////////////////////////////////////////////////////// +struct var_decl_closure : boost::spirit::closure<var_decl_closure, declaration_type> +{ + member1 val; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// symbols_with_data +// +// Helper class for inserting an item with data into a symbol table +// +/////////////////////////////////////////////////////////////////////////////// +template <typename T, typename InitT> +class symbols_with_data +{ +public: + typedef + symbol_inserter<T, boost::spirit::impl::tst<T, char> > + symbol_inserter_t; + + symbols_with_data(symbol_inserter_t const &add_, InitT const &data_) : + add(add_), data(as_actor<InitT>::convert(data_)) + { + } + + template <typename IteratorT> + symbol_inserter_t const & + operator()(IteratorT const &first_, IteratorT const &last) const + { + IteratorT first = first_; + return add(first, last, data()); + } + +private: + symbol_inserter_t const &add; + typename as_actor<InitT>::type data; +}; + +template <typename T, typename CharT, typename InitT> +inline +symbols_with_data<T, InitT> +symbols_gen(symbol_inserter<T, boost::spirit::impl::tst<T, CharT> > const &add_, + InitT const &data_) +{ + return symbols_with_data<T, InitT>(add_, data_); +} + +/////////////////////////////////////////////////////////////////////////////// +// The var_decl_list grammar parses variable declaration list + +struct var_decl_list : + public grammar<var_decl_list, var_decl_closure::context_t> +{ + template <typename ScannerT> + struct definition + { + definition(var_decl_list const &self) + { + // pass variable type returned from 'type' to list closure member 0 + decl = type[self.val = arg1] >> +space_p >> list(self.val); + + // m0 to access arg 0 of list --> passing variable type down to ident + list = ident(list.val) >> *(',' >> ident(list.val)); + + // store identifier and type into the symbol table + ident = (*alnum_p)[symbols_gen(symtab.add, ident.val)]; + + // the type of the decl is returned in type's closure member 0 + type = + str_p("int")[type.val = construct_<string>(arg1, arg2)] + | str_p("real")[type.val = construct_<string>(arg1, arg2)] + ; + + BOOST_SPIRIT_DEBUG_RULE(decl); + BOOST_SPIRIT_DEBUG_RULE(list); + BOOST_SPIRIT_DEBUG_RULE(ident); + BOOST_SPIRIT_DEBUG_RULE(type); + } + + rule<ScannerT> const& + start() const { return decl; } + + private: + typedef rule<ScannerT, var_decl_closure::context_t> rule_t; + rule_t type; + rule_t list; + rule_t ident; + symbols<declaration_type> symtab; + + rule<ScannerT> decl; // start rule + }; +}; + +/////////////////////////////////////////////////////////////////////////////// +// main entry point +int main() +{ + var_decl_list decl; + declaration_type type; + char const *pbegin = "int var1"; + + if (parse (pbegin, decl[assign(type)]).full) { + cout << endl + << "Parsed variable declarations successfully!" << endl + << "Detected type: " << declaration_type::vartype(type) + << " (" << string(type) << ")" + << endl; + } else { + cout << endl + << "Parsing the input stream failed!" + << endl; + } + return 0; +} + Added: trunk/opentrep/test/parsers/schedule_parser.cpp =================================================================== --- trunk/opentrep/test/parsers/schedule_parser.cpp (rev 0) +++ trunk/opentrep/test/parsers/schedule_parser.cpp 2009-07-12 13:36:35 UTC (rev 120) @@ -0,0 +1,911 @@ +// C +#include <assert.h> +// STL +#include <iostream> +#include <sstream> +#include <fstream> +#include <string> +#include <map> +#include <set> +#include <vector> +// Boost (Extended STL) +#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/date_time/gregorian/gregorian.hpp> +// Boost Spirit (Parsing) +//#define BOOST_SPIRIT_DEBUG +#include <boost/spirit/core.hpp> +#include <boost/spirit/attribute.hpp> +#include <boost/spirit/utility/functor_parser.hpp> +#include <boost/spirit/utility/loops.hpp> +#include <boost/spirit/utility/chset.hpp> +#include <boost/spirit/utility/confix.hpp> +#include <boost/spirit/iterator/file_iterator.hpp> +#include <boost/spirit/actor/push_back_actor.hpp> +#include <boost/spirit/actor/assign_actor.hpp> + +// Type definitions +typedef char char_t; +//typedef char const* iterator_t; +typedef boost::spirit::file_iterator<char_t> iterator_t; +typedef boost::spirit::scanner<iterator_t> scanner_t; +typedef boost::spirit::rule<scanner_t> rule_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; + 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 +// +/////////////////////////////////////////////////////////////////////////////// +namespace { + + /** Store the parsed airline code. */ + struct store_airline_code { + store_airline_code (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + std::string lAirlineCode (iStr, iStrEnd); + _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(); + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the parsed flight number. */ + struct store_flight_number { + store_flight_number (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (unsigned int iNumber) const { + _flightPeriod._flightNumber = iNumber; + // std::cout << "Flight number: " << iNumber << std::endl; + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the start of the date range. */ + struct store_date_range_start { + store_date_range_start (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + _flightPeriod._dateRangeStart = _flightPeriod.getDate(); + // std::cout << "Date Range Start: " + // << _flightPeriod._dateRangeStart << std::endl; + + // Reset the number of seconds + _flightPeriod._itSeconds = 0; + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the end of the date range. */ + struct store_date_range_end { + store_date_range_end (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (iterator_t iStr, iterator_t iStrEnd) 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). */ + struct store_dow { + store_dow (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + std::string lDow (iStr, iStrEnd); + _flightPeriod._dow = lDow; + // std::cout << "DOW: " << lDow << std::endl; + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the parsed board point. */ + struct store_board_point { + store_board_point (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + std::string lBoardPoint (iStr, iStrEnd); + // 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); + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the parsed off point. */ + struct store_off_point { + store_off_point (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + std::string lOffPoint (iStr, iStrEnd); + _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); + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the board time. */ + struct store_board_time { + store_board_time (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + _flightPeriod._itLeg._boardTime = _flightPeriod.getTime(); + + // Reset the number of seconds + _flightPeriod._itSeconds = 0; + + // Reset the date off-set + _flightPeriod._dateOffSet = 0; + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the off time. */ + struct store_off_time { + store_off_time (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + _flightPeriod._itLeg._offTime = _flightPeriod.getTime(); + + // 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; + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the elapsed time. */ + struct store_elapsed_time { + store_elapsed_time (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + _flightPeriod._itLeg._elapsed = _flightPeriod.getTime(); + + // 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; + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the parsed cabin code. */ + struct store_cabin_code { + store_cabin_code (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (char iChar) const { + _flightPeriod._itCabin._cabinCode = iChar; + // std::cout << "Cabin code: " << iChar << std::endl; + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the parsed capacity. */ + struct store_capacity { + store_capacity (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + void operator() (double iReal) 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); + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store whether or not all the segments are the same. */ + struct store_segment_specificity { + store_segment_specificity (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + void operator() (char iChar) 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(); + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the board point of the segment. */ + struct store_segment_board_point { + store_segment_board_point (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + std::string lBoardPoint (iStr, iStrEnd); + _flightPeriod._itSegment._boardPoint = lBoardPoint; + // std::cout << "Board point: " << lBoardPoint << std::endl; + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the off point of the segment. */ + struct store_segment_off_point { + store_segment_off_point (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + std::string lOffPoint (iStr, iStrEnd); + _flightPeriod._itSegment._offPoint = lOffPoint; + // std::cout << "Off point: " << lOffPoint << std::endl; + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the off point of the segment. */ + struct store_segment_cabin_code { + store_segment_cabin_code (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + void operator() (char iChar) const { + _flightPeriod._itSegmentCabin._cabinCode = iChar; + // std::cout << "Cabin code: " << iChar << std::endl; + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Store the classes of the segment-cabin. */ + struct store_classes { + store_classes (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + std::string lClasses (iStr, iStrEnd); + _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); + } + } + + FlightPeriod_T& _flightPeriod; + }; + + /** Mark the end of the flight-period parsing. */ + struct do_end_flight { + do_end_flight (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) {} + + // void operator() (char iChar) const { + void operator() (iterator_t iStr, iterator_t iStrEnd) const { + // std::cout << "End of Flight-Period " << std::endl; + + assert (_flightPeriod._legAlreadyDefined == true); + _flightPeriod._legList.push_back (_flightPeriod._itLeg); + + // The lists of legs and cabins must be reset + _flightPeriod._legAlreadyDefined = false; + _flightPeriod._itLeg._cabinList.clear(); + + // Display the result + _flightPeriod.display(); + } + + FlightPeriod_T& _flightPeriod; + }; +} + +// /////////// Utilities ///////////// +/** 1-digit-integer parser */ +boost::spirit::int_parser<unsigned int, 10, 1, 1> int1_p; +/** 2-digit-integer parser */ +boost::spirit::uint_parser<int, 10, 2, 2> uint2_p; +/** 4-digit-integer parser */ +boost::spirit::uint_parser<int, 10, 4, 4> uint4_p; +/** Up-to-4-digit-integer parser */ +boost::spirit::uint_parser<int, 10, 1, 4> uint1_4_p; + +/////////////////////////////////////////////////////////////////////////////// +// +// Our calculator grammar (using subrules) +// +/////////////////////////////////////////////////////////////////////////////// + /** + AirlineCode; FlightNumber; DateRangeStart; DateRangeEnd; DOW; + (list) BoardPoint; OffPoint; BoardTime; DateOffSet; OffTime; + ElapsedTime; + (list) CabinCode; Capacity; + SegmentSpecificty (0 or 1); + (list) (optional BoardPoint; OffPoint); CabinCode; Classes + + 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; + + Grammar: + DOW ::= int + FlightKey ::= AirlineCode ';' FlightNumber + ';' DateRangeStart ';' DateRangeEnd ';' DOW + LegKey ::= BoardPoint ';' OffPoint + LegDetails ::= BoardTime ['/' BoardDateOffSet] + ';' OffTime ['/' BoardDateOffSet] + ';' Elapsed + LegCabinDetails ::= CabinCode ';' Capacity + Leg ::= LegKey ';' LegDetails (';' CabinDetails)+ + SegmentKey ::= BoardPoint ';' OffPoint + SegmentCabinDetails ::= CabinCode ';' Classes + FullSegmentCabinDetails::= (';' SegmentCabinDetails)+ + GeneralSegments ::= '0' (';' SegmentCabinDetails)+ + SpecificSegments ::= '1' (';' SegmentKey + ';' FullSegmentCabinDetails)+ + Segment ::= GeneralSegment | SpecificSegment + FlightPeriod ::= FlightKey (';' Leg)+ + (';' Segment)+ ';' EndOfFlight + EndOfFlight ::= ';' + */ + +using namespace boost::spirit; + +/** Grammar for the Flight-Period parser. */ +struct FlightPeriodParser : + public boost::spirit::grammar<FlightPeriodParser> { + + FlightPeriodParser (FlightPeriod_T& ioFlightPeriod) + : _flightPeriod (ioFlightPeriod) { + } + + template <typename ScannerT> + struct definition { + definition (FlightPeriodParser const& self) { + + flight_period_list = *( boost::spirit::comment_p("//") + | boost::spirit::comment_p("/*", "*/") + | flight_period ) + ; + + flight_period = flight_key + >> +( ';' >> leg ) + >> +( ';' >> segment ) + >> flight_period_end[do_end_flight(self._flightPeriod)] + ; + + flight_period_end = + boost::spirit::ch_p(';') + ; + + flight_key = airline_code + >> ';' >> flight_number + >> ';' >> date[store_date_range_start(self._flightPeriod)] + >> ';' >> date[store_date_range_end(self._flightPeriod)] + >> ';' >> dow[store_dow(self._flightPeriod)] + ; + + airline_code = + lexeme_d[ (repeat_p(2,3)[chset_p("0-9A-Z")])[store_airline_code(self._flightPeriod)] ] + ; + + flight_number = + lexeme_d[ limit_d(0u, 9999u)[uint1_4_p][store_flight_number(self._flightPeriod)] ] + ; + + date = + lexeme_d[ limit_d(2000u,2099u)[uint4_p][assign_a(self._flightPeriod._itYear)] + >> '-' >> limit_d(1u,12u)[uint2_p][assign_a(self._flightPeriod._itMonth)] + >> '-' >> limit_d(1u,31u)[uint2_p][assign_a(self._flightPeriod._itDay)] ] + ; + + dow = + lexeme_d[ repeat_p(7)[chset_p("0-1")] ] + ; + + leg = leg_key >> ';' >> leg_details >> +( ';' >> cabin_details ) + ; + + leg_key = + (repeat_p(3)[chset_p("0-9A-Z")])[store_board_point(self._flightPeriod)] + >> ';' + >> (repeat_p(3)[chset_p("0-9A-Z")])[store_off_point(self._flightPeriod)] + ; + + leg_details = + time[store_board_time(self._flightPeriod)] + >> !(date_offset) + >> ';' + >> time[store_off_time(self._flightPeriod)] + >> !(date_offset) + >> ';' + >> time[store_elapsed_time(self._flightPeriod)] + ; + + time = lexeme_d[ limit_d(0u,23u)[uint2_p][assign_a(self._flightPeriod._itHours)] + >> ':' >> limit_d(0u,59u)[uint2_p][assign_a(self._flightPeriod._itMinutes)] + >> !(':' >> limit_d(0u,59u)[uint2_p][assign_a(self._flightPeriod._itSeconds)]) ] + ; + + date_offset = + boost::spirit::ch_p('/') + >> (int1_p)[boost::spirit::assign_a(self._flightPeriod._dateOffSet)] + ; + + cabin_details = (chset_p("A-Z"))[store_cabin_code(self._flightPeriod)] + >> ';' >> (boost::spirit::ureal_p)[store_capacity(self._flightPeriod)] + ; + + segment_key = + (repeat_p(3)[chset_p("0-9A-Z")])[store_segment_board_point(self._flightPeriod)] + >> ';' + >> (repeat_p(3)[chset_p("0-9A-Z")])[store_segment_off_point(self._flightPeriod)] + ; + + segment = + general_segments | specific_segments + ; + + general_segments = + boost::spirit::ch_p('0')[store_segment_specificity(self._flightPeriod)] + >> +(';' >> segment_cabin_details) + ; + + specific_segments = + boost::spirit::ch_p('1')[store_segment_specificity(self._flightPeriod)] + >> +(';' >> segment_key >> full_segment_cabin_details) + ; + + full_segment_cabin_details = + +(';' >> segment_cabin_details) + ; + + segment_cabin_details = + (chset_p("A-Z"))[store_segment_cabin_code(self._flightPeriod)] + >> ';' >> (repeat_p(1,26)[chset_p("A-Z")])[store_classes(self._flightPeriod)] + ; + + BOOST_SPIRIT_DEBUG_NODE (flight_period_list); + BOOST_SPIRIT_DEBUG_NODE (flight_period); + BOOST_SPIRIT_DEBUG_NODE (flight_period_end); + BOOST_SPIRIT_DEBUG_NODE (flight_key); + BOOST_SPIRIT_DEBUG_NODE (airline_code); + BOOST_SPIRIT_DEBUG_NODE (flight_number); + BOOST_SPIRIT_DEBUG_NODE (date); + BOOST_SPIRIT_DEBUG_NODE (dow); + BOOST_SPIRIT_DEBUG_NODE (leg); + BOOST_SPIRIT_DEBUG_NODE (leg_key); + BOOST_SPIRIT_DEBUG_NODE (leg_details); + BOOST_SPIRIT_DEBUG_NODE (time); + BOOST_SPIRIT_DEBUG_NODE (date_offset); + BOOST_SPIRIT_DEBUG_NODE (cabin_details); + BOOST_SPIRIT_DEBUG_NODE (segment); + BOOST_SPIRIT_DEBUG_NODE (segment_key); + BOOST_SPIRIT_DEBUG_NODE (general_segments); + BOOST_SPIRIT_DEBUG_NODE (specific_segments); + BOOST_SPIRIT_DEBUG_NODE (full_segment_cabin_details); + BOOST_SPIRIT_DEBUG_NODE (segment_cabin_details); + } + + boost::spirit::rule<ScannerT> flight_period_list, flight_period, + flight_period_end, flight_key, airline_code, flight_number, + date, dow, leg, leg_key, leg_details, time, date_offset, cabin_details, + segment, segment_key, general_segments, specific_segments, + full_segment_cabin_details, segment_cabin_details; + + boost::spirit::rule<ScannerT> const& start() const { return flight_period_list; } + }; + + FlightPeriod_T& _flightPeriod; +}; + +// /////////////// M A I N ///////////////// +int main (int argc, char* argv[]) { + try { + + // File to be parsed + std::string lFilename ("world_schedule.csv"); + + // Read the command-line parameters + if (argc >= 1 && argv[1] != NULL) { + std::istringstream istr (argv[1]); + istr >> lFilename; + } + + // Open the file + iterator_t lFileIterator (lFilename); + if (!lFileIterator) { + std::cerr << "The file " << lFilename << " can not be open." << std::endl; + } + + // Create an EOF iterator + iterator_t lFileIteratorEnd = lFileIterator.make_end(); + + // Instantiate the structure that will hold the result of the parsing. + FlightPeriod_T lFlightPeriod; + FlightPeriodParser lFlightPeriodParser (lFlightPeriod); + boost::spirit::parse_info<iterator_t> info = + boost::spirit::parse (lFileIterator, lFileIteratorEnd, + lFlightPeriodParser, + boost::spirit::space_p); + + // DEBUG + std::cout << "Flight Period:" << std::endl; + lFlightPeriod.display(); + + std::cout << "-------------------------" << std::endl; + if (info.full) { + std::cout << "Parsing succeeded" << std::endl; + + } else { + std::cout << "Parsing failed" << std::endl; + } + std::cout << "-------------------------" << std::endl; + + } catch (const std::exception& stde) { + std::cerr << "Standard exception: " << stde.what() << std::endl; + return -1; + + } catch (...) { + return -1; + } + + return 0; +} Added: trunk/opentrep/test/parsers/test_full_calculator.sh =================================================================== --- trunk/opentrep/test/parsers/test_full_calculator.sh (rev 0) +++ trunk/opentrep/test/parsers/test_full_calculator.sh 2009-07-12 13:36:35 UTC (rev 120) @@ -0,0 +1,25 @@ +#!/bin/sh + +INSTALL_DIR=`grep "^prefix =" ../Makefile | cut -d"=" -d" " -f3` +TST_PROG=./full_calculator +LATUS_API_VERSION=`grep "^LATUS_API_VERSION =" ../Makefile | cut -d"=" -d" " -f3` +LATUS_LIBRARY_NAME=`grep "^LATUS_LIBRARY_NAME =" ../Makefile | cut -d"=" -d" " -f3` +LATUS_LIB=lib${LATUS_LIBRARY_NAME}-${LATUS_API_VERSION}.so + +if [ ! -x ${TST_PROG} ]; +then + echo "The sample program does not seem to have been compiled. Try 'make check' first." + exit -1 +fi + +if [ "$1" = "-h" -o "$1" = "-H" -o "$1" = "--h" -o "$1" = "--help" ]; +then + echo "Usage: $0 [<String to be parsed>]" + echo " The list to be parsed should contain floating point numbers" + echo " separated by commas, and should not contain spaces." + echo " Example: 10.2,5.4" + echo "The program parses a line and fills a flight-period structure." + exit 0 +fi + +${TST_PROG} $1 Property changes on: trunk/opentrep/test/parsers/test_full_calculator.sh ___________________________________________________________________ Added: svn:executable + * Added: trunk/opentrep/test/parsers/test_parameter_parser.sh =================================================================== --- trunk/opentrep/test/parsers/test_parameter_parser.sh (rev 0) +++ trunk/opentrep/test/parsers/test_parameter_parser.sh 2009-07-12 13:36:35 UTC (rev 120) @@ -0,0 +1,25 @@ +#!/bin/sh + +INSTALL_DIR=`grep "^prefix =" ../Makefile | cut -d"=" -d" " -f3` +TST_PROG=./parameter_parser +LATUS_API_VERSION=`grep "^LATUS_API_VERSION =" ../Makefile | cut -d"=" -d" " -f3` +LATUS_LIBRARY_NAME=`grep "^LATUS_LIBRARY_NAME =" ../Makefile | cut -d"=" -d" " -f3` +LATUS_LIB=lib${LATUS_LIBRARY_NAME}-${LATUS_API_VERSION}.so + +if [ ! -x ${TST_PROG} ]; +then + echo "The sample program does not seem to have been compiled. Try 'make check' first." + exit -1 +fi + +if [ "$1" = "-h" -o "$1" = "-H" -o "$1" = "--h" -o "$1" = "--help" ]; +then + echo "Usage: $0 [<String to be parsed>]" + echo " The list to be parsed should contain floating point numbers" + echo " separated by commas, and should not contain spaces." + echo " Example: 10.2,5.4" + echo "The program parses a line and fills a flight-period structure." + exit 0 +fi + +${TST_PROG} $1 Property changes on: trunk/opentrep/test/parsers/test_parameter_parser.sh ___________________________________________________________________ Added: svn:executable + * Added: trunk/opentrep/test/parsers/test_schedule_parser.sh =================================================================== --- trunk/opentrep/test/parsers/test_schedule_parser.sh (rev 0) +++ trunk/opentrep/test/parsers/test_schedule_parser.sh 2009-07-12 13:36:35 UTC (rev 120) @@ -0,0 +1,25 @@ +#!/bin/sh + +INSTALL_DIR=`grep "^prefix =" ../Makefile | cut -d"=" -d" " -f3` +TST_PROG=./schedule_parser +LATUS_API_VERSION=`grep "^LATUS_API_VERSION =" ../Makefile | cut -d"=" -d" " -f3` +LATUS_LIBRARY_NAME=`grep "^LATUS_LIBRARY_NAME =" ../Makefile | cut -d"=" -d" " -f3` +LATUS_LIB=lib${LATUS_LIBRARY_NAME}-${LATUS_API_VERSION}.so + +if [ ! -x ${TST_PROG} ]; +then + echo "The sample program does not seem to have been compiled. Try 'make check' first." + exit -1 +fi + +if [ "$1" = "-h" -o "$1" = "-H" -o "$1" = "--h" -o "$1" = "--help" ]; +then + echo "Usage: $0 [<String to be parsed>]" + echo " The list to be parsed should contain floating point numbers" + echo " separated by commas, and should not contain spaces." + echo " Example: 10.2,5.4" + echo "The program parses a line and fills a flight-period structure." + exit 0 +fi + +${TST_PROG} $1 Property changes on: trunk/opentrep/test/parsers/test_schedule_parser.sh ___________________________________________________________________ Added: svn:executable + * Added: trunk/opentrep/test/parsers/world_schedule.csv =================================================================== --- trunk/opentrep/test/parsers/world_schedule.csv (rev 0) +++ trunk/opentrep/test/parsers/world_schedule.csv 2009-07-12 13:36:35 UTC (rev 120) @@ -0,0 +1,21 @@ +// Flights: AirlineCode; FlightNumber; Date-Range; ; DOW; Legs; Segments; +// Legs: BoardPoint; OffPoint; BoardTime; ArrivalDateOffSet; ArrivalTime; +// ElapsedTime; LegCabins; +// LegCabins: CabinCode; Capacity; +// Segments: Specific; +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; +BA; 279; 2007-04-20; 2007-06-30; 1111111; LHR; LAX; 10:05; 13:10; 11:05; F; 5; J; 12; W; 20; Y; 300; 0; F; FA; J; JCDI; W; WT; Y; YBHKMRVNELSQO; +BA; 295; 2007-04-20; 2007-06-30; 1111111; LHR; ORD; 11:35; 14:00; 08:25; F; 5; J; 12; W; 20; Y; 300; 0; F; FA; J; JCDI; W; WT; Y; YBHKMRVNELSQO; +BA; 341; 2007-04-20; 2007-06-30; 1111111; NCE; LHR; 08:55; 10:05; 02:10; J; 12; Y; 300; 0; J; JCDI; Y; YBHKMRVNEQLSO; +BA; 343; 2007-04-20; 2007-06-30; 1111111; NCE; LHR; 11:00; 12:15; 02:15; J; 12; Y; 300; 0; J; JCDI; Y; YBHKMRVNEQLSO; +BA; 345; 2007-04-20; 2007-06-30; 1111111; NCE; LHR; 16:20; 17:25; 02:05; J; 12; Y; 300; 0; J; JCDI; Y; YBHKMRVNEQLSO; +BA; 347; 2007-04-20; 2007-06-30; 1111111; NCE; LHR; 13:55; 15:00; 02:05; J; 12; Y; 300; 0; J; JCDI; Y; YBHKMRVNEQLSO; +AA; 101; 2007-04-20; 2007-06-30; 1111111; LHR; JFK; 09:55; 12:50; 07:55; G; 300; 0; G; GHQKLMVSOWN; +AA; 117; 2007-04-20; 2007-06-30; 1111111; JFK; LAX; 14:20; 17:25; 06:05; F; 12; J; 20; Y; 300; 0; F; FA; J; JDI; Y; YBGHQKLMVSOWN; +AA; 181; 2007-04-20; 2007-06-30; 1111111; JFK; LAX; 17:00; 20:00; 06:00; F; 12; J; 20; Y; 300; 0; F; FA; J; JDI; Y; YBHKMLWVGSNOQ; +AA; 585; 2007-04-20; 2007-06-30; 1111111; JFK; MIA; 15:40; 18:50; 03:10; F; 12; Y; 300; 0; F; FAP; Y; YBHKMLWVGSONQ; \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |