OKlibrary  0.2.1.6
ParsingSingleResult.hpp
Go to the documentation of this file.
00001 // Oliver Kullmann, 13.5.2005 (Swansea)
00002 /* Copyright 2005 - 2007, 2009 Oliver Kullmann
00003 This file is part of the OKlibrary. OKlibrary is free software; you can redistribute
00004 it and/or modify it under the terms of the GNU General Public License as published by
00005 the Free Software Foundation and included in this library; either version 3 of the
00006 License, or any later version. */
00007 
00014 #ifndef PARSINGSINGLERESULT_jzRtL77Yq1
00015 #define PARSINGSINGLERESULT_jzRtL77Yq1
00016 
00017 #define BOOST_SPIRIT_USE_OLD_NAMESPACE
00018 
00019 #include <string>
00020 #include <stdexcept>
00021 
00022 #include <boost/spirit/include/classic_core.hpp>
00023 #include <boost/spirit/include/classic_file_iterator.hpp>
00024 #include <boost/spirit/include/classic_position_iterator.hpp>
00025 #include <boost/filesystem/path.hpp>
00026 #include <boost/lexical_cast.hpp>
00027 
00028 #include <OKlib/Programming/Parsing/ParserBase.hpp>
00029 
00030 #include <OKlib/Experimentation/Competition/SingleResult.hpp>
00031 
00032 namespace OKlib {
00033   namespace SATCompetition {
00034 
00035     struct ParserError : std::runtime_error {
00036       ParserError(const std::string& message) : std::runtime_error(message) {}
00037     };
00038 
00039     // #######################################################
00040 
00041     template <class ResultElement, typename CharT = char, typename ParseIterator = const CharT*>
00042     class ParserResultElement;
00043 
00044     // ---------------------------------------------------------------------------------------------------------
00045 
00046     template <typename CharT, typename ParseIterator>
00047     class ParserResultElement<SuperSeries, CharT, ParseIterator> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00048       SuperSeries& s;
00049       struct action {
00050         SuperSeries& s;
00051         action(SuperSeries& s) : s(s) {}
00052         void operator() (const ParseIterator begin, const ParseIterator end) const {
00053           s = SuperSeries(std::string(begin, end));
00054         }
00055       };
00056     public :
00057       ParserResultElement(SuperSeries& s) : s(s) {
00058         this -> parser_ = (+(boost::spirit::alnum_p | boost::spirit::ch_p('-')))[action(s)];
00059       }
00060     };
00061 
00062     template <typename CharT, typename ParseIterator>
00063     class ParserResultElement<RandomKSat, CharT, ParseIterator> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00064       RandomKSat& s;
00065       typedef RandomKSat::natural_number_type natural_number_type;
00066       natural_number_type k;
00067       struct action1 {
00068         natural_number_type& k;
00069         action1(natural_number_type& k) : k(k) {}
00070         void operator() (natural_number_type k_) const {
00071           k = k_;
00072         }
00073       };
00074       struct action2 {
00075         natural_number_type& k;
00076         RandomKSat& s;
00077         action2(natural_number_type& k, RandomKSat& s) : k(k), s(s) {}
00078         void operator() (const ParseIterator begin, const ParseIterator end) const {
00079           s = RandomKSat(std::string(begin, end), k);
00080         }
00081       };
00082     public :
00083       ParserResultElement(RandomKSat& s) : s(s) {
00084         this -> parser_ = ((boost::spirit::uint_parser<natural_number_type, 10, 1, 2>())[action1(k)] >> boost::spirit::str_p("SAT"))[action2(k,s)];
00085       }
00086     };
00087 
00088     // ---------------------------------------------------------------------------------------------------------
00089 
00090     template <typename CharT, typename ParseIterator>
00091     class ParserResultElement<Series, CharT, ParseIterator> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00092       Series& s;
00093       struct action {
00094         Series& s;
00095         action(Series& s) : s(s) {}
00096         void operator() (const ParseIterator begin, const ParseIterator end) const {
00097           s = Series(std::string(begin, end));
00098         }
00099       };
00100       typedef typename ::OKlib::Parser::ParserBase<CharT, ParseIterator>::Rule Rule;
00101       Rule filename;
00102     public :
00103       ParserResultElement(Series& s) : s(s) {
00104         filename = +(boost::spirit::alnum_p | boost::spirit::ch_p('-') | boost::spirit::ch_p('.') | boost::spirit::ch_p('_'));
00105         this -> parser_ = (+(filename >> boost::spirit::ch_p('/')) >> filename)[action(s)];
00106       }
00107     };
00108 
00109     template <typename CharT, typename ParseIterator>
00110     class ParserResultElement<RandomKSat_n, CharT, ParseIterator> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00111       RandomKSat_n& s;
00112       typedef RandomKSat::natural_number_type natural_number_type;
00113       natural_number_type n;
00114       struct action1 {
00115         natural_number_type& n;
00116         action1(natural_number_type& n) : n(n) {}
00117         void operator() (const natural_number_type n_) const {
00118           n = n_;
00119         }
00120       };
00121       struct action2 {
00122         natural_number_type& n;
00123         RandomKSat_n& s;
00124         action2(natural_number_type& n, RandomKSat_n& s) : n(n), s(s) {}
00125         void operator() (const ParseIterator begin, const ParseIterator end) const {
00126           s = RandomKSat_n(std::string(begin, end), n);
00127         }
00128       };
00129       typedef typename ::OKlib::Parser::ParserBase<CharT, ParseIterator>::Rule Rule;
00130       Rule filename;
00131       Rule basename;
00132     public :
00133       ParserResultElement(RandomKSat_n& s) : s(s) {
00134         filename = +(boost::spirit::alnum_p | boost::spirit::ch_p('-'));
00135         basename = +(
00136                      boost::spirit::alnum_p  |
00137                      boost::spirit::ch_p('.') |
00138                      (boost::spirit::ch_p('-') >> ((boost::spirit::alnum_p - boost::spirit::ch_p('v')) | boost::spirit::ch_p('.') | boost::spirit::ch_p('-'))) |
00139                      (boost::spirit::str_p("-v") >> (boost::spirit::alpha_p | boost::spirit::ch_p('.') | boost::spirit::ch_p('-')) |
00140                      (boost::spirit::str_p("-v") >> boost::spirit::uint_p >>
00141                       (boost::spirit::alpha_p | boost::spirit::ch_p('.') | boost::spirit::ch_p('-'))))
00142                      )
00143           >> boost::spirit::str_p("-v") >> boost::spirit::uint_p[action1(n)];
00144         this -> parser_ = (+(filename >> boost::spirit::ch_p('/')) >> basename)[action2(n,s)];
00145         //ToDo: The following comment into the parsing documentation:
00146         // parser_ = *boost::spirit::ch_p('a') >> boost::spirit::str_p("ab"); //CAUTION: does not accept "ab"
00147       }
00148     };
00149 
00150     // ---------------------------------------------------------------------------------------------------------
00151 
00152     template <typename CharT, typename ParseIterator>
00153     class ParserResultElement<Benchmark, CharT, ParseIterator> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00154       Benchmark& s;
00155       struct action {
00156         Benchmark& s;
00157         action(Benchmark& s) : s(s) {}
00158         void operator() (const ParseIterator begin, const ParseIterator end) const {
00159           s = Benchmark(std::string(begin, end));
00160         }
00161       };
00162     public :
00163       ParserResultElement(Benchmark& s) : s(s) {
00164         this -> parser_ = (boost::spirit::str_p("bench") >> boost::spirit::uint_p)[action(s)];
00165       }
00166     };
00167 
00168     // ---------------------------------------------------------------------------------------------------------
00169 
00170     template <typename CharT, typename ParseIterator>
00171     class ParserResultElement<Solver, CharT, ParseIterator> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00172       Solver& s;
00173       struct action {
00174         Solver& s;
00175         action(Solver& s) : s(s) {}
00176         void operator() (const ParseIterator begin, const ParseIterator end) const {
00177           s = Solver(std::string(begin, end));
00178         }
00179       };
00180     public :
00181       ParserResultElement(Solver& s) : s(s) {
00182         this -> parser_ = (boost::spirit::str_p("solver") >> boost::spirit::uint_p)[action(s)];
00183       }
00184     };
00185 
00186     // ---------------------------------------------------------------------------------------------------------
00187 
00188     template <typename CharT, typename ParseIterator>
00189     class ParserResultElement<SATStatus, CharT, ParseIterator> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00190       SATStatus& s;
00191       struct action {
00192         SATStatus& s;
00193         action(SATStatus& s) : s(s) {}
00194         void operator() (const unsigned int& code) const {
00195           switch (code) {
00196           case unknown :
00197             s = SATStatus(unknown); break;
00198           case sat :
00199             s = SATStatus(sat); break;
00200           case unsat :
00201             s = SATStatus(unsat); break;
00202           default :
00203             s = SATStatus(error);
00204           }
00205         }
00206       };
00207     public :
00208       ParserResultElement(SATStatus& s) : s(s) {
00209         this -> parser_ = boost::spirit::uint_p[action(s)];
00210       }
00211     };
00212 
00213 
00214     // ---------------------------------------------------------------------------------------------------------
00215 
00216     template <typename CharT, typename ParseIterator>
00217     class ParserResultElement<AverageTime, CharT, ParseIterator> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00218       AverageTime& s;
00219       typedef AverageTime::floating_point_type floating_point_type;
00220       struct action {
00221         AverageTime& s;
00222         action(AverageTime& s) : s(s) {}
00223         void operator() (const floating_point_type x) const {
00224           s = AverageTime(x);
00225         }
00226       };
00227     public :
00228       ParserResultElement(AverageTime& s) : s(s) {
00229         this -> parser_ = boost::spirit::real_parser<floating_point_type, boost::spirit::ureal_parser_policies<floating_point_type> >()[action(s)];
00230       }
00231     };
00232 
00233     // ---------------------------------------------------------------------------------------------------------
00234     
00235     template <typename CharT, typename ParseIterator>
00236     class ParserResultElement<TimeOut, CharT, ParseIterator> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00237       TimeOut& s;
00238       struct action {
00239         TimeOut& s;
00240         action(TimeOut& s) : s(s) {}
00241         typedef TimeOut::natural_number_type natural_number_type;
00242         void operator() (const natural_number_type x) const {
00243           s = TimeOut(x);
00244         }
00245       };
00246     public :
00247       ParserResultElement(TimeOut& s) : s(s) {
00248         this -> parser_ = boost::spirit::uint_p[action(s)];
00249       }
00250     };
00251 
00252     // #######################################################
00253 
00254     template <typename CharT, typename ParseIterator>
00255     struct ParserEmpty : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00256       ParserEmpty() {
00257         this -> parser_ = ! boost::spirit::nothing_p;
00258         // ToDo: Is this the best implementation of the "neutral parser" ?
00259       }
00260     };
00261 
00262      template <typename CharT, typename ParseIterator>
00263     struct ParserThreeElements : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00264       ParserThreeElements() {
00265         this -> parser_ = boost::spirit::ch_p(' ') >> (+boost::spirit::alpha_p) >> boost::spirit::uint_p >> boost::spirit::ch_p(' ') >> boost::spirit::uint_p >> boost::spirit::ch_p(' ') >> boost::spirit::uint_p;
00266       }
00267     };
00268    
00269     // #######################################################
00270     // #######################################################
00271 
00272     template <class Result, typename CharT, typename ParseIterator, class ParserExtension>
00273     class ParserResult;
00274 
00275     template <typename CharT, typename ParseIterator, class ParserExtension>
00276     class ParserResult<Result, CharT, ParseIterator, ParserExtension> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00277       Result& r;
00278       ParserResultElement<SuperSeries, CharT, ParseIterator> p_sup_ser;
00279       ParserResultElement<Series, CharT, ParseIterator> p_ser;
00280       ParserResultElement<Benchmark, CharT, ParseIterator> p_bench;
00281       ParserResultElement<Solver, CharT, ParseIterator> p_solv;
00282       ParserResultElement<SATStatus, CharT, ParseIterator> p_sat_stat;
00283       ParserResultElement<AverageTime, CharT, ParseIterator> p_avg;
00284       ParserResultElement<TimeOut, CharT, ParseIterator> p_tmo;
00285       ParserExtension p_ext;
00286     public :
00287       typedef Result result_type;
00288       ParserResult(Result& r) : r(r), p_sup_ser(*r.sup_ser), p_ser(*r.ser), p_bench(*r.bench), p_solv(*r.solv), p_sat_stat(*r.sat_stat), p_avg(*r.avg), p_tmo(*r.tmo) {
00289         this -> parser_ = p_sup_ser.parser() >> boost::spirit::ch_p(' ') >> p_ser.parser() >> boost::spirit::ch_p(' ') >> p_bench.parser() >> boost::spirit::ch_p(' ') >> p_solv.parser() >> boost::spirit::ch_p(' ') >> p_sat_stat.parser() >> boost::spirit::ch_p(' ') >> p_avg.parser() >> boost::spirit::ch_p(' ') >> p_tmo.parser() >> p_ext.parser();
00290       }
00291     };
00292 
00293     template <typename CharT, typename ParseIterator, class ParserExtension>
00294     class ParserResult<ResultRandomSat, CharT, ParseIterator, ParserExtension> : public ::OKlib::Parser::ParserBase<CharT, ParseIterator> {
00295       ResultRandomSat& r;
00296       ParserResultElement<RandomKSat, CharT, ParseIterator> p_sup_ser;
00297       ParserResultElement<RandomKSat_n, CharT, ParseIterator> p_ser;
00298       ParserResultElement<Benchmark, CharT, ParseIterator> p_bench;
00299       ParserResultElement<Solver, CharT, ParseIterator> p_solv;
00300       ParserResultElement<SATStatus, CharT, ParseIterator> p_sat_stat;
00301       ParserResultElement<AverageTime, CharT, ParseIterator> p_avg;
00302       ParserResultElement<TimeOut, CharT, ParseIterator> p_tmo;
00303       ParserExtension p_ext;
00304     public :
00305       typedef ResultRandomSat result_type;
00306       ParserResult(ResultRandomSat& r) : r(r), p_sup_ser(*r.sup_ser), p_ser(*r.ser), p_bench(*r.bench), p_solv(*r.solv), p_sat_stat(*r.sat_stat), p_avg(*r.avg), p_tmo(*r.tmo) {
00307         this -> parser_ = p_sup_ser.parser() >> boost::spirit::ch_p(' ') >> p_ser.parser() >> boost::spirit::ch_p(' ') >> p_bench.parser() >> boost::spirit::ch_p(' ') >> p_solv.parser() >> boost::spirit::ch_p(' ') >> p_sat_stat.parser() >> boost::spirit::ch_p(' ') >> p_avg.parser() >> boost::spirit::ch_p(' ') >> p_tmo.parser() >> p_ext.parser();
00308       }
00309     };
00310 
00311   }
00312 
00313 }
00314 
00315 #endif