Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define BOOST_IOSTREAMS_NO_LIB
- #include "pgn_games_extractor.h"
- #include <boost/spirit/include/qi.hpp>
- #include <boost/fusion/include/adapt_struct.hpp>
- #include <boost/iostreams/device/mapped_file.hpp>
- BOOST_FUSION_ADAPT_STRUCT(loloof64::pgn_tag, key, value)
- BOOST_FUSION_ADAPT_STRUCT(loloof64::game_move, move_number, white_move, black_move, result)
- BOOST_FUSION_ADAPT_STRUCT(loloof64::pgn_game, header, moves)
- /**
- * With the help of Sehe on stackoverflow
- * http://stackoverflow.com/questions/34211394/boost-spirit-2-is-there-a-way-to-know-what-is-the-parser-progression-percentag
- */
- namespace loloof64 {
- namespace qi = boost::spirit::qi;
- template <typename Iterator> struct pgn_parser : qi::grammar<Iterator, std::vector<pgn_game>, qi::space_type>
- {
- pgn_parser(Iterator start, Iterator end) : pgn_parser::base_type(games), reportProgress ( ReportProgressFunc (start, end) )
- {
- using namespace qi;
- const std::string no_move;
- result.add
- ("1-0", result_t::white_won)
- ("0-1", result_t::black_won)
- ("1/2-1/2", result_t::draw)
- ("*", result_t::undecided);
- quoted_string = '"' >> *~char_('"') >> '"';
- tag = '[' >> +alnum >> quoted_string >> ']';
- header = +tag;
- regular_move = lit("O-O-O") | "O-O" | (+char_("a-hNBRQK") >> +char_("a-h1-8x=NBRQK") >> -lit("e.p."));
- single_move = raw [ regular_move >> -char_("+#") ];
- full_move = omit[pos.current_pos [reportProgress(_1)] ] >> uint_
- >> (lexeme["..." >> attr(no_move)] | "." >> single_move)
- >> (single_move | attr(no_move))
- >> -result;
- game_description = +full_move;
- single_game = -header >> game_description;
- games = pos.save_start_pos >> *single_game;
- BOOST_SPIRIT_DEBUG_NODES(
- (tag)(header)(quoted_string)(regular_move)(single_move)
- (full_move)(game_description)(single_game)(games)
- )
- }
- private:
- qi::rule<Iterator, pgn_tag(), qi::space_type> tag;
- qi::rule<Iterator, std::vector<pgn_tag>, qi::space_type> header;
- qi::rule<Iterator, game_move(), qi::space_type> full_move;
- qi::rule<Iterator, std::vector<game_move>, qi::space_type> game_description;
- qi::rule<Iterator, pgn_game(), qi::space_type> single_game;
- qi::rule<Iterator, std::vector<pgn_game>, qi::space_type> games;
- // lexemes
- qi::symbols<char, result_t> result;
- qi::rule<Iterator, std::string()> quoted_string;
- qi::rule<Iterator> regular_move;
- qi::rule<Iterator, std::string()> single_move;
- CurrentPos<Iterator> pos;
- struct ReportProgressFunc
- {
- Iterator start, end;
- mutable int percentageInt = 0;
- template <typename T>
- void operator()(T pos) const
- {
- int newPercentInt = pos * 100 / std::distance(start, end);
- if ((newPercentInt - percentageInt) > 0)
- {
- percentageInt = newPercentInt;
- std::cout << newPercentInt << " %" << std::endl;
- }
- }
- ReportProgressFunc(Iterator start, Iterator end): start(start), end(end) {}
- };
- phx::function<ReportProgressFunc> reportProgress;
- };
- }
- loloof64::PgnGamesExtractor::PgnGamesExtractor(std::string const &inputFilePath) {
- parseInput(inputFilePath);
- }
- loloof64::PgnGamesExtractor::~PgnGamesExtractor() {
- // dtor
- }
- void loloof64::PgnGamesExtractor::parseInput(std::string const &inputFilePath) {
- boost::iostreams::mapped_file_source mf(inputFilePath);
- auto iter = mf.begin();
- auto end = mf.end();
- typedef char const* It;
- loloof64::pgn_parser<It> parser(iter, end);
- std::vector<loloof64::pgn_game> temp_games;
- bool success = boost::spirit::qi::phrase_parse(iter, end, parser, boost::spirit::qi::space, temp_games);
- if (success && iter == end) {
- games.swap(temp_games);
- } else {
- std::string error_fragment(iter, end);
- throw PgnParsingException("Failed to parse the input at :'" + error_fragment + "' !");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement