You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

102 lines
2.6 KiB

#pragma once
#include "cell.h"
#include <vector>
#include <boost/tokenizer.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/variant/recursive_wrapper.hpp>
#include <boost/spirit/include/support_line_pos_iterator.hpp>
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
typedef boost::spirit::line_pos_iterator<std::string::const_iterator> pos_iterator_t;
typedef std::vector<cell> row;
typedef std::vector<cell> cells;
BOOST_FUSION_ADAPT_STRUCT(
cell,
(Type, type)
(Color, color)
)
template<typename It>
struct annotation_f {
typedef void result_type;
annotation_f(It first) : first(first) {}
It const first;
template<typename Val, typename First, typename Last>
void operator()(Val& v, First f, Last l) const {
do_annotate(v, f, l, first);
}
private:
void static do_annotate(cell& c, It f, It l, It first) {
c.row = get_line(f) - 1;
c.column = get_column(first, f) / 2;
}
static void do_annotate(...) { std::cerr << "(not having LocationInfo)\n"; }
};
template <typename It>
struct MinigridParser : qi::grammar<It, row()>
{
MinigridParser(It first) : MinigridParser::base_type(row_), annotate(first)
{
using namespace qi;
type_.add
("W", Type::Wall)
(" ", Type::Floor)
("D", Type::Door)
("L", Type::LockedDoor)
("K", Type::Key)
("A", Type::Ball)
("B", Type::Box)
("G", Type::Goal)
("V", Type::Lava)
("n", Type::SlipperyNorth)
("e", Type::SlipperyEast)
("s", Type::SlipperySouth)
("w", Type::SlipperyWest)
("X", Type::Agent)
("Z", Type::Adversary);
color_.add
("R", Color::Red)
("G", Color::Green)
("B", Color::Blue)
("P", Color::Purple)
("Y", Color::Yellow)
(" ", Color::None);
cell_ = type_ > color_;
row_ = (cell_ % -qi::char_("\n"));
auto set_location_info = annotate(_val, _1, _3);
on_success(cell_, set_location_info);
BOOST_SPIRIT_DEBUG_NODE(type_);
BOOST_SPIRIT_DEBUG_NODE(color_);
BOOST_SPIRIT_DEBUG_NODE(cell_);
}
private:
phoenix::function<annotation_f<It>> annotate;
qi::symbols<char, Type> type_;
qi::symbols<char, Color> color_;
qi::rule<It, cell()> cell_;
qi::rule<It, row()> row_;
};
typedef boost::tokenizer< boost::escaped_list_separator<char> , std::string::const_iterator, std::string> Tokenizer;
//std::ostream& operator<<(std::ostream& os, const row& r);