Advertisement
loloof64

Parsing Pgn File and getting progress

Dec 12th, 2015
503
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.92 KB | None | 0 0
  1. #include "pgn_games_extractor.h"
  2. #include <boost/spirit/include/qi.hpp>
  3. #include <boost/fusion/include/adapt_struct.hpp>
  4. #include <tuple>
  5.  
  6. #include <iostream>
  7.  
  8. BOOST_FUSION_ADAPT_STRUCT(loloof64::pgn_tag, key, value)
  9. BOOST_FUSION_ADAPT_STRUCT(loloof64::game_move, move_number, white_move, black_move, result)
  10. BOOST_FUSION_ADAPT_STRUCT(loloof64::pgn_game, header, moves)
  11.  
  12. namespace loloof64 {
  13. namespace qi = boost::spirit::qi;
  14.  
  15. typedef std::tuple<std::size_t, game_move> move_t;
  16. typedef std::tuple<std::vector<pgn_tag>, std::vector<move_t>> game_t;
  17. typedef std::tuple<std::size_t, std::vector<game_t>> pgn_t;
  18.  
  19. template <typename Iterator> struct pgn_parser : qi::grammar<Iterator, std::vector<pgn_game>, qi::space_type> {
  20.     pgn_parser() : pgn_parser::base_type(games) {
  21.         using namespace qi;
  22.  
  23.         CurrentPos<Iterator> filepos;
  24.  
  25.         const std::string no_move;
  26.         result.add
  27.             ("1-0",     result_t::white_won)
  28.             ("0-1",     result_t::black_won)
  29.             ("1/2-1/2", result_t::draw)
  30.             ("*",       result_t::undecided);
  31.  
  32.         quoted_string    = '"' >> *~char_('"') >> '"';
  33.         tag              = '[' >> +alnum >> quoted_string >> ']';
  34.         header           = +tag;
  35.         regular_move     = lit("O-O-O") | "O-O" | (+char_("a-hNBRQK") >> +char_("a-h1-8x=NBRQK") >> -lit("e.p."));
  36.         single_move      = raw [ regular_move >> -char_("+#") ];
  37.         full_move        = filepos.current_pos >> uint_
  38.             >> (lexeme["..." >> attr(no_move)] | "." >> single_move)
  39.             >> (single_move | attr(no_move))
  40.             >> -result;
  41.  
  42.         game_description = +full_move;
  43.         single_game      = -header >> game_description;
  44.         games            = filepos.save_start_pos >> *single_game;
  45.  
  46.         BOOST_SPIRIT_DEBUG_NODES(
  47.                     (tag)(header)(quoted_string)(regular_move)(single_move)
  48.                     (full_move)(game_description)(single_game)(games)
  49.                 )
  50.     }
  51.  
  52.   private:
  53.     qi::rule<Iterator, pgn_tag(),              qi::space_type> tag;
  54.     qi::rule<Iterator, std::vector<pgn_tag>,   qi::space_type> header;
  55.  
  56.     qi::rule<Iterator, move_t(),               qi::space_type> full_move;
  57.     qi::rule<Iterator, std::vector<move_t>,    qi::space_type> game_description;
  58.  
  59.     qi::rule<Iterator, game_t(),               qi::space_type> single_game;
  60.     qi::rule<Iterator, pgn_t(),  qi::space_type> games;
  61.  
  62.     // lexemes
  63.     qi::symbols<char, result_t> result;
  64.     qi::rule<Iterator, std::string()> quoted_string;
  65.     qi::rule<Iterator> regular_move;
  66.     qi::rule<Iterator, std::string()> single_move;
  67. };
  68. }
  69.  
  70. loloof64::PgnGamesExtractor::PgnGamesExtractor(std::string inputFilePath) {
  71.     std::ifstream inputFile(inputFilePath);
  72.     parseInput(inputFile);
  73. }
  74.  
  75. loloof64::PgnGamesExtractor::PgnGamesExtractor(std::istream &inputFile) { parseInput(inputFile); }
  76.  
  77. loloof64::PgnGamesExtractor::~PgnGamesExtractor() {
  78.     // dtor
  79. }
  80.  
  81. void loloof64::PgnGamesExtractor::parseInput(std::istream &inputFile) {
  82.     if (inputFile.fail() || inputFile.bad())
  83.         throw new InputFileException("Could not read the input file !");
  84.  
  85.     typedef boost::spirit::istream_iterator It;
  86.     loloof64::pgn_parser<It> parser;
  87.     std::vector<loloof64::pgn_game> temp_games;
  88.  
  89.     It iter(inputFile >> std::noskipws), end;
  90.  
  91.     //////////////////////////////////
  92.     std::cout << "About to parse the file" << std::endl;
  93.     //////////////////////////////////
  94.  
  95.     bool success = boost::spirit::qi::phrase_parse(iter, end, parser, boost::spirit::qi::space, temp_games);
  96.  
  97.     //////////////////////////////////
  98.     std::cout << "Finished to parse the file" << std::endl;
  99.     //////////////////////////////////
  100.  
  101.     if (success && iter == end) {
  102.         games.swap(temp_games);
  103.     } else {
  104.         std::string error_fragment(iter, end);
  105.         throw PgnParsingException("Failed to parse the input at :'" + error_fragment + "' !");
  106.     }
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement