Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pgn_games_extractor.h"
- #include <boost/spirit/include/qi.hpp>
- #include <boost/fusion/include/adapt_struct.hpp>
- #include <tuple>
- #include <iostream>
- 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)
- namespace loloof64 {
- namespace qi = boost::spirit::qi;
- typedef std::tuple<std::size_t, game_move> move_t;
- typedef std::tuple<std::vector<pgn_tag>, std::vector<move_t>> game_t;
- typedef std::tuple<std::size_t, std::vector<game_t>> pgn_t;
- template <typename Iterator> struct pgn_parser : qi::grammar<Iterator, std::vector<pgn_game>, qi::space_type> {
- pgn_parser() : pgn_parser::base_type(games) {
- using namespace qi;
- CurrentPos<Iterator> filepos;
- 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 = filepos.current_pos >> uint_
- >> (lexeme["..." >> attr(no_move)] | "." >> single_move)
- >> (single_move | attr(no_move))
- >> -result;
- game_description = +full_move;
- single_game = -header >> game_description;
- games = filepos.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, move_t(), qi::space_type> full_move;
- qi::rule<Iterator, std::vector<move_t>, qi::space_type> game_description;
- qi::rule<Iterator, game_t(), qi::space_type> single_game;
- qi::rule<Iterator, pgn_t(), 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;
- };
- }
- loloof64::PgnGamesExtractor::PgnGamesExtractor(std::string inputFilePath) {
- std::ifstream inputFile(inputFilePath);
- parseInput(inputFile);
- }
- loloof64::PgnGamesExtractor::PgnGamesExtractor(std::istream &inputFile) { parseInput(inputFile); }
- loloof64::PgnGamesExtractor::~PgnGamesExtractor() {
- // dtor
- }
- void loloof64::PgnGamesExtractor::parseInput(std::istream &inputFile) {
- if (inputFile.fail() || inputFile.bad())
- throw new InputFileException("Could not read the input file !");
- typedef boost::spirit::istream_iterator It;
- loloof64::pgn_parser<It> parser;
- std::vector<loloof64::pgn_game> temp_games;
- It iter(inputFile >> std::noskipws), end;
- //////////////////////////////////
- std::cout << "About to parse the file" << std::endl;
- //////////////////////////////////
- bool success = boost::spirit::qi::phrase_parse(iter, end, parser, boost::spirit::qi::space, temp_games);
- //////////////////////////////////
- std::cout << "Finished to parse the file" << std::endl;
- //////////////////////////////////
- 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