Advertisement
loloof64

Parsing Pgn File and getting progress (cpp) solved

Dec 13th, 2015
420
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.23 KB | None | 0 0
  1. #define BOOST_IOSTREAMS_NO_LIB
  2.  
  3. #include "pgn_games_extractor.h"
  4.  
  5. #include <boost/spirit/include/qi.hpp>
  6. #include <boost/fusion/include/adapt_struct.hpp>
  7. #include <boost/iostreams/device/mapped_file.hpp>
  8.  
  9. BOOST_FUSION_ADAPT_STRUCT(loloof64::pgn_tag, key, value)
  10. BOOST_FUSION_ADAPT_STRUCT(loloof64::game_move, move_number, white_move, black_move, result)
  11. BOOST_FUSION_ADAPT_STRUCT(loloof64::pgn_game, header, moves)
  12.  
  13. /**
  14.  * With the help of Sehe on stackoverflow
  15.  * http://stackoverflow.com/questions/34211394/boost-spirit-2-is-there-a-way-to-know-what-is-the-parser-progression-percentag
  16.  */
  17.  
  18. namespace loloof64 {
  19. namespace qi = boost::spirit::qi;
  20.  
  21. template <typename Iterator> struct pgn_parser : qi::grammar<Iterator, std::vector<pgn_game>, qi::space_type>
  22. {
  23.     pgn_parser(Iterator start, Iterator end) : pgn_parser::base_type(games), reportProgress ( ReportProgressFunc (start, end) )
  24.     {
  25.         using namespace qi;
  26.  
  27.         const std::string no_move;
  28.         result.add
  29.             ("1-0",     result_t::white_won)
  30.             ("0-1",     result_t::black_won)
  31.             ("1/2-1/2", result_t::draw)
  32.             ("*",       result_t::undecided);
  33.  
  34.         quoted_string    = '"' >> *~char_('"') >> '"';
  35.         tag              = '[' >> +alnum >> quoted_string >> ']';
  36.         header           = +tag;
  37.         regular_move     = lit("O-O-O") | "O-O" | (+char_("a-hNBRQK") >> +char_("a-h1-8x=NBRQK") >> -lit("e.p."));
  38.         single_move      = raw [ regular_move >> -char_("+#") ];
  39.         full_move        = omit[pos.current_pos [reportProgress(_1)] ] >> uint_
  40.             >> (lexeme["..." >> attr(no_move)] | "." >> single_move)
  41.             >> (single_move | attr(no_move))
  42.             >> -result;
  43.  
  44.         game_description = +full_move;
  45.         single_game      = -header >> game_description;
  46.         games            = pos.save_start_pos >> *single_game;
  47.  
  48.         BOOST_SPIRIT_DEBUG_NODES(
  49.                     (tag)(header)(quoted_string)(regular_move)(single_move)
  50.                     (full_move)(game_description)(single_game)(games)
  51.                 )
  52.     }
  53.  
  54.   private:
  55.     qi::rule<Iterator, pgn_tag(),              qi::space_type> tag;
  56.     qi::rule<Iterator, std::vector<pgn_tag>,   qi::space_type> header;
  57.  
  58.     qi::rule<Iterator, game_move(),            qi::space_type> full_move;
  59.     qi::rule<Iterator, std::vector<game_move>, qi::space_type> game_description;
  60.  
  61.     qi::rule<Iterator, pgn_game(),               qi::space_type> single_game;
  62.     qi::rule<Iterator, std::vector<pgn_game>,  qi::space_type> games;
  63.  
  64.     // lexemes
  65.     qi::symbols<char, result_t> result;
  66.     qi::rule<Iterator, std::string()> quoted_string;
  67.     qi::rule<Iterator> regular_move;
  68.     qi::rule<Iterator, std::string()> single_move;
  69.  
  70.     CurrentPos<Iterator> pos;
  71.  
  72.     struct ReportProgressFunc
  73.     {
  74.         Iterator start, end;
  75.  
  76.         mutable int percentageInt = 0;
  77.  
  78.         template <typename T>
  79.         void operator()(T pos) const
  80.         {
  81.             int newPercentInt = pos * 100 / std::distance(start, end);
  82.             if ((newPercentInt - percentageInt) > 0)
  83.             {
  84.                 percentageInt = newPercentInt;
  85.                 std::cout << newPercentInt << " %" << std::endl;
  86.             }
  87.         }
  88.  
  89.         ReportProgressFunc(Iterator start, Iterator end): start(start), end(end) {}
  90.     };
  91.  
  92.     phx::function<ReportProgressFunc> reportProgress;
  93. };
  94. }
  95.  
  96. loloof64::PgnGamesExtractor::PgnGamesExtractor(std::string const &inputFilePath) {
  97.     parseInput(inputFilePath);
  98. }
  99.  
  100. loloof64::PgnGamesExtractor::~PgnGamesExtractor() {
  101.     // dtor
  102. }
  103.  
  104. void loloof64::PgnGamesExtractor::parseInput(std::string const &inputFilePath) {
  105.     boost::iostreams::mapped_file_source mf(inputFilePath);
  106.  
  107.     auto iter = mf.begin();
  108.     auto end = mf.end();
  109.  
  110.     typedef char const* It;
  111.     loloof64::pgn_parser<It> parser(iter, end);
  112.     std::vector<loloof64::pgn_game> temp_games;
  113.  
  114.     bool success = boost::spirit::qi::phrase_parse(iter, end, parser, boost::spirit::qi::space, temp_games);
  115.  
  116.     if (success && iter == end) {
  117.         games.swap(temp_games);
  118.     } else {
  119.         std::string error_fragment(iter, end);
  120.         throw PgnParsingException("Failed to parse the input at :'" + error_fragment + "' !");
  121.     }
  122. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement