// decomposes a rule (A -> B C D E ...) into the rules (A -> B#C#D E), (B#C#D -> B#C D), (B#C -> B C), ... respectively. // might expand 'nonterminals' // might rewrite 'rule_to_decompose' void decompose(rule &rule_to_decompose, set<string> &nonterminals, rules &decomposed_rules) { string temp; if (rule_to_decompose.size() == 2) { if (is_in(rule_to_decompose[1], nonterminals)) { cerr << " ERROR : irregular occurence of chain rule (i.e. A -> B)! - ignored " << '\n'; return; } else decomposed_rules.insert(rule_to_decompose); } else { for (size_t i = 1; i<rule_to_decompose.size();++i) if (!is_in(rule_to_decompose[i], nonterminals)) { temp = "#" + rule_to_decompose[i]; nonterminals.insert(temp); decomposed_rules.insert(rule{ temp, rule_to_decompose[i] }); replace(rule_to_decompose.begin() + i, rule_to_decompose.end(), rule_to_decompose[i], temp); } while(rule_to_decompose.size() > 3) { temp = rule_to_decompose[1] + "#" + rule_to_decompose[2]; nonterminals.insert(temp); decomposed_rules.insert(rule{ temp, rule_to_decompose[1], rule_to_decompose[2] }); rule_to_decompose[1] = temp; rule_to_decompose.erase(rule_to_decompose.begin() + 2); } decomposed_rules.insert(rule_to_decompose); } }