void REParser::appendQuantifier(const QString & token, TokenList & q) { const QString s(token.mid(1, token.size()-2)); int i(s.indexOf(QChar(','))); if(i<0) { i=s.toInt(); q.appendQUANTIFIER(Quantifier(i, i)); } else { const QString l(s.left(i)); const QString r(s.mid(i+1)); int min(0); int max(-1); if(l.size())min=l.toInt(); if(r.size())max=r.toInt(); q.appendQUANTIFIER(Quantifier(min, max)); } }
ALWAYS_INLINE Quantifier Parser::consumeGreedyQuantifier() { switch (peek()) { case '?': consume(); return Quantifier(Quantifier::Greedy, 0, 1); case '*': consume(); return Quantifier(Quantifier::Greedy, 0); case '+': consume(); return Quantifier(Quantifier::Greedy, 1); case '{': { SavedState state(*this); consume(); // Accept: {n}, {n,}, {n,m}. // Reject: {n,m} where n > m. // Ignore: Anything else, such as {n, m}. if (!peekIsDigit()) { state.restore(); return Quantifier(); } unsigned min = consumeNumber(); unsigned max = min; if (peek() == ',') { consume(); max = peekIsDigit() ? consumeNumber() : Quantifier::Infinity; } if (peek() != '}') { state.restore(); return Quantifier(); } consume(); if (min > max) { setError(QuantifierOutOfOrder); return Quantifier(Quantifier::Error); } return Quantifier(Quantifier::Greedy, min, max); } default: return Quantifier(); // No quantifier. } }
ReSyntaxExprNode* ReSyntaxTreeBuilder::Factor() { ReSyntaxExprNode* res; if (tokenizer.Match(__R('('))) { if ((tokenizer.Match(__R('<'), 1) || tokenizer.Match(__R('?'), 1)) && (tokenizer.Match(__R('='), 2) || tokenizer.Match(__R('!'), 2)) ) { res = LookAround(); } else if (tokenizer.Match(__R('<'), 1) && (tokenizer.IsPosDigital(2) || tokenizer.Match(__R('$'), 2))) { res = BackTracedGroup(); Quantifier(res); } else if (tokenizer.Match(__R('<'), 1) && (tokenizer.IsPosDigital(2) || tokenizer.Match(__R('#'), 2))) { res = BackReference(); Quantifier(res); } else //只能通过左括号判断捕获列表 { res = CapturedGroup(); Quantifier(res); } } else if (tokenizer.Match(__R('['))) { if (tokenizer.Match(__R('^'), 1)) { res = NoSelection(); Quantifier(res); } else { res = Selection(); Quantifier(res); } } else if (tokenizer.Finish()) { return nullptr; } else if (!tokenizer.IsPosSpecial()) { ReCharExprNode* tmp = nullptr; Char(tmp); res = tmp; Quantifier(res); } else { return nullptr; } return res; }