Пример #1
0
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.
    }
}
Пример #2
0
static bool parseHSLParameters(CSSParserTokenRange& range, RGBA32& result, bool parseAlpha)
{
    ASSERT(range.peek().functionId() == CSSValueHsl || range.peek().functionId() == CSSValueHsla);
    CSSParserTokenRange args = consumeFunction(range);
    CSSPrimitiveValue* hslValue = consumeNumber(args, ValueRangeAll);
    if (!hslValue)
        return false;
    double colorArray[3];
    colorArray[0] = (((hslValue->getIntValue() % 360) + 360) % 360) / 360.0;
    for (int i = 1; i < 3; i++) {
        if (!consumeCommaIncludingWhitespace(args))
            return false;
        hslValue = consumePercent(args, ValueRangeAll);
        if (!hslValue)
            return false;
        double doubleValue = hslValue->getDoubleValue();
        colorArray[i] = clampTo<double>(doubleValue, 0.0, 100.0) / 100.0; // Needs to be value between 0 and 1.0.
    }
    double alpha = 1.0;
    if (parseAlpha) {
        if (!consumeCommaIncludingWhitespace(args))
            return false;
        if (!consumeNumberRaw(args, alpha))
            return false;
        alpha = clampTo<double>(alpha, 0.0, 1.0);
    }
    result = makeRGBAFromHSLA(colorArray[0], colorArray[1], colorArray[2], alpha);
    return args.atEnd();
}
// http://www.w3.org/TR/css3-syntax/#consume-a-numeric-token
CSSParserToken CSSTokenizer::consumeNumericToken()
{
    CSSParserToken token = consumeNumber();
    if (nextCharsAreIdentifier())
        token.convertToDimensionWithUnit(consumeName());
    else if (consumeIfNext('%'))
        token.convertToPercentage();
    return token;
}
Пример #4
0
AnimExpression::Token AnimExpression::consumeToken(const QString& str, QString::const_iterator& iter) const {
    if (!_tokenStack.empty()) {
        Token top = _tokenStack.top();
        _tokenStack.pop();
        return top;
    } else {
        while (iter != str.end()) {
            if (iter->isSpace()) {
                ++iter;
            } else if (iter->isLetter()) {
                return consumeIdentifier(str, iter);
            } else if (iter->isDigit()) {
                return consumeNumber(str, iter);
            } else {
                switch (iter->unicode()) {
                case '&': return consumeAnd(str, iter);
                case '|': return consumeOr(str, iter);
                case '>': return consumeGreaterThan(str, iter);
                case '<': return consumeLessThan(str, iter);
                case '(': ++iter; return Token(Token::LeftParen);
                case ')': ++iter; return Token(Token::RightParen);
                case '!': return consumeNot(str, iter);
                case '-': ++iter; return Token(Token::Minus);
                case '+': ++iter; return Token(Token::Plus);
                case '*': ++iter; return Token(Token::Multiply);
                case '/': ++iter; return Token(Token::Divide);
                case '%': ++iter; return Token(Token::Modulus);
                case ',': ++iter; return Token(Token::Comma);
                default:
                    qCCritical(animation) << "AnimExpression: unexpected char" << *iter << "at index " << (int)(iter - str.begin());
                    return Token(Token::Error);
                }
            }
        }
        return Token(Token::End);
    }
}
Пример #5
0
void Tokenizer::shift()
{
    mpCurrent.reset();

    if (mBlockComment)
    {
        skipEOL();
    }
    else
    {
        skipWhiteSpaces();
        if (mpInput->eof())
            return;
    }

    mpCurrent.reset(new Token);
    mpCurrent->setLine(line());
    mpCurrent->setBeginColumn(column());

    if (mBlockComment)
    {
        consumeCStyleBlockComment();
        return;
    }

    auto ch = mpInput->get();
    if (isLetter(ch) || isUnderscore(ch))
    {
        consumeIdentifier(ch);
    }
    else if (isBiwiseOperatorSymbol(ch))
    {
        mpCurrent->setType(Token::TYPE_BITWISE_OPERATOR);
        absorbed(ch);
        mpCurrent->addChar(ch);
        mpCurrent->setEndColumn(column());
    }
    else if (isDot(ch) && consumeDot(ch))
    {
        // nothing
    }
    else if ((isDecimalDigit(ch) || isDot(ch) || isSign(ch)) && consumeNumber(ch))
    {
        // nothing
    }
    else if (isQuotationMark(ch))
    {
        if (!consumeString(ch))
            shift();
    }
    else if (isCStyleInitialCommentChar(ch))
    {
        consumeComment(ch);
    }
    else if (isArrowSymbol(ch) && consumeArrow(ch))
    {
        // nothing
    }
    else if (isBracket(ch))
    {
        mpCurrent->setType(Token::TYPE_BRACKET);
        absorbed(ch);
        mpCurrent->addChar(ch);
        mpCurrent->setEndColumn(column());
    }
    else if (isAngleBracket(ch))
    {
        mpCurrent->setType(Token::TYPE_ANGLE_BRACKET);
        absorbed(ch);
        mpCurrent->addChar(ch);
        mpCurrent->setEndColumn(column());
    }
    else if (isDelimiter(ch))
    {
        mpCurrent->setType(Token::TYPE_DELIMITER);
        absorbed(ch);
        mpCurrent->addChar(ch);
        mpCurrent->setEndColumn(column());
    }
    else if (isOperator(ch) && consumeEqualOperator(ch))
    {
        // nothing
    }
    else if (isOperator(ch))
    {
        mpCurrent->setType(Token::TYPE_OPERATOR);
        absorbed(ch);
        mpCurrent->addChar(ch);
        mpCurrent->setEndColumn(column());
    }
    else if (isAsterisk(ch))
    {
        mpCurrent->setType(Token::TYPE_ASTERISK);
        absorbed(ch);
        mpCurrent->addChar(ch);
        mpCurrent->setEndColumn(column());
    }
    else
    {
        mpCurrent.reset();
    }
}