void HighlightStateBuilder::build(StringListLangElem *elem, HighlightState *state) { const string &name = elem->getName(); StringDefs *alternatives = elem->getAlternatives(); WordList wordList; bool doubleQuoted = false, nonDoubleQuoted = false, buildAsWordList = true; for (StringDefs::const_iterator it = alternatives->begin(); it != alternatives->end(); ++it) { const string &rep = (*it)->toString(); // double quoted strings generate WordListRules, otherwise simple ListRules // we don't allow double quoted strings mixed with non double quoted if (((*it)->isDoubleQuoted() && nonDoubleQuoted) || (!(*it)->isDoubleQuoted() && doubleQuoted)) { throw HighlightBuilderException( "cannot mix double quoted and non double quoted", elem); } doubleQuoted = (*it)->isDoubleQuoted(); nonDoubleQuoted = !(*it)->isDoubleQuoted(); wordList.push_back(rep); // now check whether we must build a word list rule (word boundary) or an // ordinary list; as soon as we find something that is not to be isolated // we set buildAsWordList as false if (buildAsWordList && (!doubleQuoted || !is_to_isolate(rep))) { buildAsWordList = false; } } HighlightRulePtr rule; if (buildAsWordList) rule = HighlightRulePtr(highlightRuleFactory->createWordListRule(name, wordList, elem->isCaseSensitive())); else rule = HighlightRulePtr(highlightRuleFactory->createListRule(name, wordList, elem->isCaseSensitive())); rule->setAdditionalInfo(elem->toStringParserInfo()); state->addRule(rule); setExitLevel(elem, rule.get()); }
/** * Case of a list of alternatives * @param elem * @param state */ void RegExpStateBuilder::build(StringListLangElem *elem, RegExpStatePointer state) { const string &name = elem->getName(); StringDefs *alternatives = elem->getAlternatives(); string stringdef; for (StringDefs::const_iterator it = alternatives->begin(); it != alternatives->end();) { const string &rep = (*it)->toString(); // check whether the regular expression string must be made non case sensitive const string &nonsensitive_processed = (elem->isCaseSensitive() ? rep : RegexPreProcessor::make_nonsensitive(rep)); // this must be checked on the original string (not the one already made // non sensistive); however, we will use the already made nonsensitive if ((*it)->isDoubleQuoted() && is_to_isolate(rep)) { // we must make a non-marking group since the string can contain // alternative symbols. For instance, // \<(?:class|for|else)\> // correctly detects 'for' only in isolation, while // (?:\<class|for|else\>) // will not stringdef += buildex_isolated(non_marking_group(nonsensitive_processed)); } else { stringdef += nonsensitive_processed; } if (++it != alternatives->end()) stringdef += '|'; // the alternatives separator } RegExpFormatterPtr formatter(new RegExpFormatter(name)); // the final regexp is enclosed in (?: ) i.e., non marking group add_exp(state, non_marking_group(stringdef), elem, formatter); build(static_cast<StateStartLangElem *>(elem), state); }