29 #include <boost/algorithm/string.hpp>
32 #define ERR_WML LOG_STREAM(err, log_wml)
40 const char* reading = source.c_str();
42 std::vector<std::string>* filled =
nullptr;
45 while (*reading != 0) {
46 if (*reading ==
'=') {
48 std::string key = boost::trim_copy(buf);
49 if(key ==
"!" || key ==
"(" || key ==
")") {
53 current->possibilities_.emplace_back();
54 filled = ¤t->possibilities_.back();
56 }
else if (*reading ==
'\n') {
58 if (filled) filled->push_back(buf);
62 }
else if (*reading ==
'|') {
63 if (!filled || !current) {
66 filled->push_back(buf);
67 current->possibilities_.emplace_back();
68 filled = ¤t->possibilities_.back();
70 }
else if (*reading ==
'\\' && reading[1] ==
'n') {
73 }
else if (*reading ==
'\\' && reading[1] ==
't') {
77 if (*reading ==
'{') {
81 filled->push_back(buf);
84 else if (*reading ==
'}') {
88 filled->push_back(
'{' + boost::trim_copy(buf));
90 }
else buf.push_back(*reading);
94 if (filled) filled->push_back(buf);
99 for(
auto rule : source) {
100 std::string key = rule.first;
102 if(key ==
"!" || key ==
"(" || key ==
")") {
105 for(std::string str : rule.second) {
107 std::vector<std::string>* filled = &
nonterminals_[key].possibilities_.back();
115 filled->push_back(buf);
123 filled->push_back(
'{' + boost::trim_copy(buf));
125 }
else buf.push_back(
c);
128 filled->push_back(buf);
138 else if (name ==
"(" ) {
141 else if (name ==
")" ) {
145 std::string result =
"";
147 std::map<std::string,nonterminal>::const_iterator found =
nonterminals_.find(name);
149 lg::log_to_chat() <<
"[context_free_grammar_generator] Warning: needed nonterminal " << name <<
" not defined\n";
150 ERR_WML <<
"[context_free_grammar_generator] Warning: needed nonterminal " << name <<
" not defined";
154 unsigned int picked = seed[seed_pos++] % got.
possibilities_.size();
156 if (picked == got.
last_) {
161 const std::vector<std::string>& used = got.
possibilities_[picked];
162 for (
unsigned int i = 0;
i < used.size();
i++) {
164 else result += used[
i];
~context_free_grammar_generator()
std::string generate() const override
Generates a possible word in the grammar set before.
std::string print_nonterminal(const std::string &name, uint32_t seed[], short int seed_pos) const
std::map< std::string, nonterminal > nonterminals_
context_free_grammar_generator(const std::string &source)
Initialisation.
static const short unsigned int seed_size
void init_seed(uint32_t seed[]) const
uint32_t next_random()
Provides the next random draw.
static lg::log_domain log_wml("wml")
Standard logging facilities (interface).
std::stringstream & log_to_chat()
Use this to show WML errors in the ingame chat.
rng * generator
This generator is automatically synced during synced context.
void trim(std::string_view &s)
std::vector< std::vector< std::string > > possibilities_