1 #include "ValueRefParser.h"
2 
3 #include "Parse.h"
4 #include "MovableEnvelope.h"
5 #include "../universe/ValueRef.h"
6 
7 #include <boost/spirit/include/phoenix.hpp>
8 
simple_double_parser_rules(const parse::lexer & tok)9 parse::detail::simple_double_parser_rules::simple_double_parser_rules(const parse::lexer& tok) :
10     simple_variable_rules("double", tok)
11 {
12     namespace phoenix = boost::phoenix;
13     namespace qi = boost::spirit::qi;
14 
15     using phoenix::new_;
16 
17     qi::_1_type _1;
18     qi::_val_type _val;
19     const boost::phoenix::function<construct_movable> construct_movable_;
20 
21     bound_variable_name
22         =   tok.Industry_
23         |   tok.TargetIndustry_
24         |   tok.Research_
25         |   tok.TargetResearch_
26         |   tok.Trade_
27         |   tok.TargetTrade_
28         |   tok.Construction_
29         |   tok.TargetConstruction_
30         |   tok.Population_
31         |   tok.TargetPopulation_
32         |   tok.TargetHappiness_
33         |   tok.Happiness_
34         |   tok.MaxFuel_
35         |   tok.Fuel_
36         |   tok.MaxShield_
37         |   tok.Shield_
38         |   tok.MaxDefense_
39         |   tok.Defense_
40         |   tok.MaxTroops_
41         |   tok.Troops_
42         |   tok.RebelTroops_
43         |   tok.MaxStructure_
44         |   tok.Structure_
45         |   tok.MaxSupply_
46         |   tok.Supply_
47         |   tok.MaxStockpile_
48         |   tok.Stockpile_
49         |   tok.Stealth_
50         |   tok.Detection_
51         |   tok.Speed_
52         |   tok.X_
53         |   tok.Y_
54         |   tok.SizeAsDouble_
55         |   tok.HabitableSize_
56         |   tok.Size_
57         |   tok.DistanceFromOriginalType_
58         |   tok.Attack_
59         |   tok.PropagatedSupplyRange_
60         ;
61 
62     free_variable_name
63         =   tok.UniverseCentreX_
64         |   tok.UniverseCentreY_
65         |   tok.UniverseWidth_
66         ;
67 
68     constant
69         =   tok.double_ [ _val = construct_movable_(new_<ValueRef::Constant<double>>(_1)) ]
70         ;
71 }
72 
double_parser_rules(const parse::lexer & tok,parse::detail::Labeller & label,const parse::detail::condition_parser_grammar & condition_parser,const parse::detail::value_ref_grammar<std::string> & string_grammar)73 parse::double_parser_rules::double_parser_rules(
74     const parse::lexer& tok,
75     parse::detail::Labeller& label,
76     const parse::detail::condition_parser_grammar& condition_parser,
77     const parse::detail::value_ref_grammar<std::string>& string_grammar
78 ) :
79     arithmetic_rules("real number", tok, label, condition_parser),
80     int_rules(tok, label, condition_parser, string_grammar),
81     simple_int_rules(tok),
82     simple_double_rules(tok),
83     int_complex_grammar(tok, label, int_rules, string_grammar),
84     double_complex_grammar(tok, label, condition_parser, string_grammar)
85 {
86     namespace phoenix = boost::phoenix;
87     namespace qi = boost::spirit::qi;
88 
89     using phoenix::new_;
90     using phoenix::static_cast_;
91 
92     qi::_1_type _1;
93     qi::_val_type _val;
94     qi::_pass_type _pass;
95     const boost::phoenix::function<detail::construct_movable> construct_movable_;
96     const boost::phoenix::function<detail::deconstruct_movable> deconstruct_movable_;
97 
98     const parse::detail::value_ref_rule<double>& simple = simple_double_rules.simple;
99 
100     int_constant_cast
101         =   tok.int_ [ _val = construct_movable_(new_<ValueRef::Constant<double>>(static_cast_<double>(_1))) ]
102         ;
103 
104     int_bound_variable_cast
105         =   simple_int_rules.bound_variable [ _val = construct_movable_(new_<ValueRef::StaticCast<int, double>>(deconstruct_movable_(_1, _pass))) ]
106         ;
107 
108     int_free_variable_cast
109         =   simple_int_rules.free_variable [ _val = construct_movable_(new_<ValueRef::StaticCast<int, double>>(deconstruct_movable_(_1, _pass))) ]
110         ;
111 
112     int_statistic_cast
113         =   int_rules.statistic_expr [ _val = construct_movable_(new_<ValueRef::StaticCast<int, double>>(deconstruct_movable_(_1, _pass))) ]
114         ;
115 
116     int_complex_variable_cast
117         =   int_complex_grammar [ _val = construct_movable_(new_<ValueRef::StaticCast<int, double>>(deconstruct_movable_(_1, _pass))) ]
118         ;
119 
120     statistic_value_ref_expr
121         = primary_expr.alias();
122 
123     primary_expr
124         =   ('(' > expr > ')')
125         |    simple
126         |    statistic_expr
127         |    int_statistic_cast
128         |    double_complex_grammar
129         |    int_constant_cast
130         |    int_free_variable_cast
131         |    int_bound_variable_cast
132         |    int_complex_variable_cast
133         ;
134 
135     int_free_variable_cast.name("integer free variable");
136     int_bound_variable_cast.name("integer bound variable");
137     int_statistic_cast.name("integer statistic");
138     int_complex_variable_cast.name("integer complex variable");
139 
140 #if DEBUG_VALUEREF_PARSERS
141     debug(int_constant_cast);
142     debug(int_free_variable_cast);
143     debug(int_bound_variable_cast);
144     debug(int_statistic_cast);
145     debug(int_complex_variable_cast);
146     debug(double_complex_variable);
147 #endif
148 }
149 
150 namespace parse {
double_free_variable(std::string & text)151     bool double_free_variable(std::string& text) {
152         const lexer tok;
153         boost::spirit::qi::in_state_type in_state;
154         parse::detail::simple_double_parser_rules simple_double_rules(tok);
155 
156         text_iterator first = text.begin();
157         text_iterator last = text.end();
158         token_iterator it = tok.begin(first, last);
159 
160         bool success = boost::spirit::qi::phrase_parse(
161             it, tok.end(), simple_double_rules.free_variable_name, in_state("WS")[tok.self]);
162 
163         return success;
164     }
165 }
166