30 #include <boost/algorithm/string.hpp>
33 #define ERR_WML LOG_STREAM(err, log_wml)
41 const char* reading = source.c_str();
43 std::vector<std::string>* filled =
nullptr;
46 while (*reading != 0) {
47 if (*reading ==
'=') {
49 std::string key = boost::trim_copy(buf);
50 if(key ==
"!" || key ==
"(" || key ==
")") {
54 current->possibilities_.emplace_back();
55 filled = ¤t->possibilities_.back();
57 }
else if (*reading ==
'\n') {
59 if (filled) filled->push_back(buf);
63 }
else if (*reading ==
'|') {
64 if (!filled || !current) {
67 filled->push_back(buf);
68 current->possibilities_.emplace_back();
69 filled = ¤t->possibilities_.back();
71 }
else if (*reading ==
'\\' && reading[1] ==
'n') {
74 }
else if (*reading ==
'\\' && reading[1] ==
't') {
78 if (*reading ==
'{') {
82 filled->push_back(buf);
85 else if (*reading ==
'}') {
89 filled->push_back(
'{' + boost::trim_copy(buf));
91 }
else buf.push_back(*reading);
95 if (filled) filled->push_back(buf);
100 for(
auto rule : source) {
101 std::string key = rule.first;
103 if(key ==
"!" || key ==
"(" || key ==
")") {
106 for(std::string str : rule.second) {
108 std::vector<std::string>* filled = &
nonterminals_[key].possibilities_.back();
116 filled->push_back(buf);
124 filled->push_back(
'{' + boost::trim_copy(buf));
126 }
else buf.push_back(
c);
129 filled->push_back(buf);
139 else if (name ==
"(" ) {
142 else if (name ==
")" ) {
146 std::string result =
"";
148 std::map<std::string,nonterminal>::const_iterator found =
nonterminals_.find(name);
150 lg::log_to_chat() <<
"[context_free_grammar_generator] Warning: needed nonterminal " << name <<
" not defined\n";
151 ERR_WML <<
"[context_free_grammar_generator] Warning: needed nonterminal " << name <<
" not defined";
155 unsigned int picked = seed[seed_pos++] % got.
possibilities_.size();
157 if (picked == got.
last_) {
162 const std::vector<std::string>& used = got.
possibilities_[picked];
163 for (
unsigned int i = 0;
i < used.size();
i++) {
165 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_