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