Exemplo n.º 1
0
std::pair<uint, std::pair<goals, goals>> parse_goals(
    parser& p,
    std::vector<warning>& warnings_list,
    const std::unordered_set<char>& declared_pieces,
    const board& declared_board)throw(goals_parse_error,parse_error){
    uint turns_limit;
    goals uppercase_player_goals;
    goals lowercase_player_goals;
    if(!p.expect_string("<GOALS>"))
        throw parse_error(p.get_line_number(), p.get_char_in_line_number(), "Goals segment must begin with \'<GOALS>\' string");
    p.expect_whitespace();
    parser_result<int> turns_limit_result = p.expect_int();
    if(!turns_limit_result)
        throw goals_parse_error(turns_limit_result.info.line_number, turns_limit_result.info.char_number, turns_limit_result.info.human_readable_info.c_str());
    if(turns_limit_result.result < 1)
        throw goals_parse_error(p.get_line_number(), p.get_char_in_line_number(), "Turns limit must be positive");
    turns_limit = turns_limit_result.result;
    p.expect_whitespace();
    if(p.expect_plain_char()!='&')
        throw goals_parse_error(p.get_line_number(), p.get_char_in_line_number(), "Turns limit must be terminated with \'&\'");
    p.expect_whitespace();
    char next_char = p.expect_plain_char();
    bool ignore;
    while(next_char == '@' || next_char == '#'){
        ignore = false;
        if(next_char == '@'){
            next_char = p.expect_plain_char();
            bool uppercase_player;
            if(isupper(next_char))
                uppercase_player = true;
            else if(islower(next_char)){
                uppercase_player = false;
                next_char = toupper(next_char);
            }
            else
                throw goals_parse_error(p.get_line_number(), p.get_char_in_line_number(), "Expected letter after \'@\'");
            if(!declared_pieces.count(next_char)){
                ignore = true;
                warnings_list.push_back(warning(p.get_line_number(), p.get_char_in_line_number(), "Undeclared piece (piece doesn't appear in the previous board declaration)"));
            }
            char piece_symbol = next_char;
            do{
                p.expect_whitespace();
                parser_result<int> x_result = p.expect_int();
                if(!x_result)
                    throw goals_parse_error(x_result.info.line_number, x_result.info.char_number, x_result.info.human_readable_info.c_str());
                if(x_result.result < 0)
                    throw goals_parse_error(p.get_line_number(), p.get_char_in_line_number(), "x coordinate must be non-negative");
                if(!p.expect_whitespace())
                    throw goals_parse_error(p.get_line_number(), p.get_char_in_line_number(), "Expected whitespace after x coordinate");
                parser_result<int> y_result = p.expect_int();
                if(!y_result)
                    throw goals_parse_error(y_result.info.line_number, y_result.info.char_number, y_result.info.human_readable_info.c_str());
                if(y_result.result < 0)
                    throw goals_parse_error(p.get_line_number(), p.get_char_in_line_number(), "y coordinate must be non-negative");
                if(!declared_board.inside(x_result.result, y_result.result)){
                    ignore = true;
                    warnings_list.push_back(warning(p.get_line_number(), p.get_char_in_line_number(), "Given point is outside the board"));
                }
                if(!ignore){
                    if(uppercase_player)
                        uppercase_player_goals.add_piece_placement_goal(piece_symbol, x_result.result, y_result.result);
                    else
                        lowercase_player_goals.add_piece_placement_goal(piece_symbol, x_result.result, y_result.result);
                }
                p.expect_whitespace();
                next_char = p.expect_plain_char();
                if(next_char != ',' && next_char != '&')
                    throw goals_parse_error(p.get_line_number(), p.get_char_in_line_number(), "Expected \',\' or \'&\'");
            }while(next_char != '&');
        }
        else{
            next_char = p.expect_plain_char();
            bool uppercase_player;
            if(isupper(next_char))
                uppercase_player = false;
            else if(islower(next_char)){
                uppercase_player = true;
                next_char = toupper(next_char);
            }
            else
                throw goals_parse_error(p.get_line_number(), p.get_char_in_line_number(), "Expected letter after \'#\'");
            if(!declared_pieces.count(next_char)){
                ignore = true;
                warnings_list.push_back(warning(p.get_line_number(), p.get_char_in_line_number(), "Undeclared piece (piece doesn't appear in the previous board declaration)"));
            }
            p.expect_whitespace();
            parser_result<int> number_of_pieces_result = p.expect_int();
            if(!number_of_pieces_result)
                throw goals_parse_error(number_of_pieces_result.info.line_number, number_of_pieces_result.info.char_number, number_of_pieces_result.info.human_readable_info.c_str());
            if(number_of_pieces_result.result < 0)
                throw goals_parse_error(p.get_line_number(), p.get_char_in_line_number(), "Number of piece captures must be non negative");
            if(!ignore){
                if(uppercase_player)
                    uppercase_player_goals.add_piece_capture_goal(next_char, number_of_pieces_result.result);
                else
                    lowercase_player_goals.add_piece_capture_goal(next_char, number_of_pieces_result.result);
            }
            p.expect_whitespace();
            if(p.expect_plain_char()!='&')
                throw goals_parse_error(p.get_line_number(), p.get_char_in_line_number(), "Capture goal must be terminated with \'&\'");
        }
        p.expect_whitespace();
        next_char = p.expect_plain_char();
    }
    return std::make_pair(turns_limit, std::make_pair(std::move(uppercase_player_goals), std::move(lowercase_player_goals)));
}