1 #include "Parse.h"
2 
3 #include "ParseImpl.h"
4 #include "MovableEnvelope.h"
5 
6 #include "../universe/Condition.h"
7 #include "../universe/FleetPlan.h"
8 #include "../util/Directories.h"
9 
10 #include <boost/spirit/include/phoenix.hpp>
11 
12 #define DEBUG_PARSERS 0
13 
14 #if DEBUG_PARSERS
15 namespace std {
operator <<(ostream & os,const std::vector<parse::detail::MovableEnvelope<FleetPlan>> &)16     inline ostream& operator<<(ostream& os, const std::vector<parse::detail::MovableEnvelope<FleetPlan>>&) { return os; }
operator <<(ostream & os,const std::vector<std::string> &)17     inline ostream& operator<<(ostream& os, const std::vector<std::string>&) { return os; }
18 }
19 #endif
20 
21 namespace {
insert_fleet_plan(std::vector<std::unique_ptr<FleetPlan>> & plans,const std::string & fleet_name,const std::vector<std::string> & ship_design_names,bool lookup_names)22     void insert_fleet_plan(
23         std::vector<std::unique_ptr<FleetPlan>>& plans,
24         const std::string& fleet_name, const std::vector<std::string>& ship_design_names,
25         bool lookup_names)
26     {
27         plans.push_back(
28             std::make_unique<FleetPlan>(
29                 fleet_name, ship_design_names, lookup_names));
30     }
31     BOOST_PHOENIX_ADAPT_FUNCTION(void, insert_fleet_plan_, insert_fleet_plan, 4)
32 
33     using start_rule_payload = std::vector<std::unique_ptr<FleetPlan>>;
34     using start_rule_signature = void(start_rule_payload&);
35 
36     struct grammar : public parse::detail::grammar<start_rule_signature> {
grammar__anonb59b72ba0111::grammar37         grammar(const parse::lexer& tok,
38                 const std::string& filename,
39                 const parse::text_iterator& first, const parse::text_iterator& last) :
40             grammar::base_type(start),
41             one_or_more_string_tokens(tok)
42         {
43             namespace phoenix = boost::phoenix;
44             namespace qi = boost::spirit::qi;
45 
46             using phoenix::new_;
47             using phoenix::push_back;
48 
49             qi::_1_type _1;
50             qi::_2_type _2;
51             qi::_3_type _3;
52             qi::_4_type _4;
53             qi::_r1_type _r1;
54             qi::omit_type omit_;
55 
56             fleet_plan
57                 =  ( omit_[tok.Fleet_]
58                 >    label(tok.Name_)   >   tok.string
59                 >    label(tok.Ships_)  >   one_or_more_string_tokens )
60                 [ insert_fleet_plan_(_r1, _1, _2, phoenix::val(true)) ]
61                 ;
62 
63             start
64             =   (+fleet_plan(_r1));
65 
66             fleet_plan.name("Fleet");
67 
68 #if DEBUG_PARSERS
69             debug(fleet_plan);
70 #endif
71 
72             qi::on_error<qi::fail>(start, parse::report_error(filename, first, last, _1, _2, _3, _4));
73         }
74 
75         using start_rule = parse::detail::rule<start_rule_signature>;
76 
77         parse::detail::Labeller label;
78         parse::detail::single_or_repeated_string<std::vector<std::string>> one_or_more_string_tokens;
79         start_rule fleet_plan;
80         start_rule start;
81     };
82 }
83 
84 namespace parse {
fleet_plans(const boost::filesystem::path & path)85     start_rule_payload fleet_plans(const boost::filesystem::path& path) {
86         const lexer lexer;
87         start_rule_payload fleet_plans_;
88         /*auto success =*/ detail::parse_file<grammar, start_rule_payload>(lexer, path, fleet_plans_);
89         return fleet_plans_;
90     }
91 }
92