1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
#include "ValueRefParser.h"
#include "ConditionParserImpl.h"
#include "MovableEnvelope.h"
#include "../universe/ValueRefs.h"
#include <boost/phoenix.hpp>
#define DEBUG_VALUEREF_PARSERS 0
// These are just here to satisfy the requirements of boost::spirit::qi::debug(<rule>).
#if DEBUG_VALUEREF_PARSERS
namespace std {
inline ostream& operator<<(ostream& os, const std::vector<std::variant<ValueRef::OpType, value_ref_payload<int>>>&) { return os; }
inline ostream& operator<<(ostream& os, const std::vector<std::variant<ValueRef::OpType, value_ref_payload<double>>>&) { return os; }
}
#endif
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
namespace parse::detail {
const reference_token_rule variable_scope(const parse::lexer& tok) {
qi::_val_type _val;
reference_token_rule variable_scope;
variable_scope
= tok.Source_ [ _val = ValueRef::ReferenceType::SOURCE_REFERENCE ]
| tok.Target_ [ _val = ValueRef::ReferenceType::EFFECT_TARGET_REFERENCE ]
| tok.LocalCandidate_ [ _val = ValueRef::ReferenceType::CONDITION_LOCAL_CANDIDATE_REFERENCE ]
| tok.RootCandidate_ [ _val = ValueRef::ReferenceType::CONDITION_ROOT_CANDIDATE_REFERENCE ]
;
variable_scope.name("Source, Target, LocalCandidate, or RootCandidate");
return variable_scope;
}
const name_token_rule container_type(const parse::lexer& tok) {
name_token_rule container_type;
container_type
= tok.Planet_
| tok.System_
| tok.Fleet_
;
container_type.name("Planet, System, or Fleet");
return container_type;
}
template <typename T>
simple_variable_rules<T>::simple_variable_rules(
const std::string& type_name, const parse::lexer& tok)
{
using phoenix::new_;
qi::_1_type _1;
qi::_val_type _val;
qi::lit_type lit;
const phoenix::function<construct_movable> construct_movable_;
free_variable
= (tok.Value_ >> !lit('('))
[ _val = construct_movable_(new_<ValueRef::Variable<T>>(
ValueRef::ReferenceType::EFFECT_TARGET_VALUE_REFERENCE)) ]
| free_variable_name
[ _val = construct_movable_(new_<ValueRef::Variable<T>>(
ValueRef::ReferenceType::NON_OBJECT_REFERENCE, _1)) ]
;
simple
= constant
| bound_variable
| free_variable
;
variable_scope_rule = variable_scope(tok);
container_type_rule = container_type(tok);
initialize_bound_variable_parser<T>(
bound_variable, unwrapped_bound_variable,
value_wrapped_bound_variable, bound_variable_name,
variable_scope_rule, container_type_rule, tok);
#if DEBUG_VALUEREF_PARSERS
debug(bound_variable_name);
debug(free_variable_name);
debug(constant);
debug(free_variable);
debug(bound_variable);
debug(simple);
#endif
unwrapped_bound_variable.name(type_name + " unwrapped bound variable name");
value_wrapped_bound_variable.name(type_name + " value-wrapped bound variable name");
bound_variable_name.name(type_name + " bound variable name");
free_variable_name.name(type_name + " free variable name");
constant.name(type_name + " constant");
free_variable.name(type_name + " free variable");
bound_variable.name(type_name + " bound variable");
simple.name(type_name + " simple variable expression");
}
// Explicit instantiation to prevent costly recompilation in multiple units
template simple_variable_rules<int>::simple_variable_rules(
const std::string& type_name, const parse::lexer& tok);
template simple_variable_rules<double>::simple_variable_rules(
const std::string& type_name, const parse::lexer& tok);
}
|