//=========================================================================== void functionTags(Grammar & rules, Element & rule, bool reset, bool mark) { if (reset || mark) { size_t maxId = 0; for (auto && elem : rules.rules()) { if (reset) const_cast<Element &>(elem).flags &= ~Element::fFunction; maxId = max((size_t)elem.id, maxId); } if (mark) { vector<bool> used(maxId, false); addFunctionTags(rules, rule, used); } } }
//=========================================================================== bool copyRules( Grammar & out, Grammar const & src, string_view rootname, bool failIfExists ) { auto root = src.element(rootname); if (!root) { logMsgError() << "Rule not found, " << rootname; return false; } auto & rules = const_cast<set<Element> &>(out.rules()); auto ib = rules.insert(*root); if (!ib.second) { if (failIfExists) { logMsgError() << "Rule already exists, " << rootname; return false; } return true; } auto & elem = *ib.first; if ((elem.flags & Element::fFunction) && (elem.flags & Element::fCharEvents) ) { logMsgError() << "Rule with both Function and Char, " << elem.value; return false; } if ((elem.flags & Element::fStartEvents) == Element::fStartEvents) { logMsgError() << "Rule with both Start and Start+, " << elem.value; return false; } if ((elem.flags & Element::fEndEvents) == Element::fEndEvents) { logMsgError() << "Rule with both End and End+, " << elem.value; return false; } if ((elem.flags & Element::fCharEvents) == Element::fCharEvents) { logMsgError() << "Rule with both Char and Char+, " << elem.value; return false; } return copyRequiredDeps(out, src, elem); }
//=========================================================================== void normalize(Grammar & rules) { rules.clearEvents(); for (auto && rule : rules.rules()) { normalize(const_cast<Element &>(rule), nullptr, rules); } }
//=========================================================================== void merge(Grammar & rules) { for (auto && rule : rules.rules()) { merge(const_cast<Element &>(rule), rules); } }