⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wrecparser.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        }    }    consume();    // lazily catch reversed ranges ([z-a])in character classes    if (constructor.isUpsideDown()) {        setError(CharacterClassOutOfOrder);        return false;    }    constructor.flush();    CharacterClass charClass = constructor.charClass();    return parseCharacterClassQuantifier(failures, charClass, invert);}bool Parser::parseNonCharacterEscape(JumpList& failures, const Escape& escape){    switch (escape.type()) {        case Escape::PatternCharacter:            ASSERT_NOT_REACHED();            return false;        case Escape::CharacterClass:            return parseCharacterClassQuantifier(failures, CharacterClassEscape::cast(escape).characterClass(), CharacterClassEscape::cast(escape).invert());        case Escape::Backreference:            return parseBackreferenceQuantifier(failures, BackreferenceEscape::cast(escape).subpatternId());        case Escape::WordBoundaryAssertion:            m_generator.generateAssertionWordBoundary(failures, WordBoundaryAssertionEscape::cast(escape).invert());            return true;        case Escape::Error:            return false;    }    ASSERT_NOT_REACHED();    return false;}Escape Parser::consumeEscape(bool inCharacterClass){    switch (peek()) {    case EndOfPattern:        setError(EscapeUnterminated);        return Escape(Escape::Error);    // Assertions    case 'b':        consume();        if (inCharacterClass)            return PatternCharacterEscape('\b');        return WordBoundaryAssertionEscape(false); // do not invert    case 'B':        consume();        if (inCharacterClass)            return PatternCharacterEscape('B');        return WordBoundaryAssertionEscape(true); // invert    // CharacterClassEscape    case 'd':        consume();        return CharacterClassEscape(CharacterClass::digits(), false);    case 's':        consume();        return CharacterClassEscape(CharacterClass::spaces(), false);    case 'w':        consume();        return CharacterClassEscape(CharacterClass::wordchar(), false);    case 'D':        consume();        return inCharacterClass            ? CharacterClassEscape(CharacterClass::nondigits(), false)            : CharacterClassEscape(CharacterClass::digits(), true);    case 'S':        consume();        return inCharacterClass            ? CharacterClassEscape(CharacterClass::nonspaces(), false)            : CharacterClassEscape(CharacterClass::spaces(), true);    case 'W':        consume();        return inCharacterClass            ? CharacterClassEscape(CharacterClass::nonwordchar(), false)            : CharacterClassEscape(CharacterClass::wordchar(), true);    // DecimalEscape    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9': {        if (peekDigit() > m_numSubpatterns || inCharacterClass) {            // To match Firefox, we parse an invalid backreference in the range [1-7]            // as an octal escape.            return peekDigit() > 7 ? PatternCharacterEscape('\\') : PatternCharacterEscape(consumeOctal());        }        int value = 0;        do {            unsigned newValue = value * 10 + peekDigit();            if (newValue > m_numSubpatterns)                break;            value = newValue;            consume();        } while (peekIsDigit());        return BackreferenceEscape(value);    }    // Octal escape    case '0':        consume();        return PatternCharacterEscape(consumeOctal());    // ControlEscape    case 'f':        consume();        return PatternCharacterEscape('\f');    case 'n':        consume();        return PatternCharacterEscape('\n');    case 'r':        consume();        return PatternCharacterEscape('\r');    case 't':        consume();        return PatternCharacterEscape('\t');    case 'v':        consume();        return PatternCharacterEscape('\v');    // ControlLetter    case 'c': {        SavedState state(*this);        consume();                int control = consume();        // To match Firefox, inside a character class, we also accept numbers        // and '_' as control characters.        if ((!inCharacterClass && !isASCIIAlpha(control)) || (!isASCIIAlphanumeric(control) && control != '_')) {            state.restore();            return PatternCharacterEscape('\\');        }        return PatternCharacterEscape(control & 31);    }    // HexEscape    case 'x': {        consume();        SavedState state(*this);        int x = consumeHex(2);        if (x == -1) {            state.restore();            return PatternCharacterEscape('x');        }        return PatternCharacterEscape(x);    }    // UnicodeEscape    case 'u': {        consume();        SavedState state(*this);        int x = consumeHex(4);        if (x == -1) {            state.restore();            return PatternCharacterEscape('u');        }        return PatternCharacterEscape(x);    }    // IdentityEscape    default:        return PatternCharacterEscape(consume());    }}void Parser::parseAlternative(JumpList& failures){    PatternCharacterSequence sequence(m_generator, failures);    while (1) {        switch (peek()) {        case EndOfPattern:        case '|':        case ')':            sequence.flush();            return;        case '*':        case '+':        case '?':        case '{': {            Quantifier q = consumeQuantifier();            if (q.type == Quantifier::None) {                sequence.append(consume());                continue;            }            if (q.type == Quantifier::Error)                return;            if (!sequence.size()) {                setError(QuantifierWithoutAtom);                return;            }            sequence.flush(q);            continue;        }        case '^':            consume();            sequence.flush();            m_generator.generateAssertionBOL(failures);            continue;        case '$':            consume();            sequence.flush();            m_generator.generateAssertionEOL(failures);            continue;        case '.':            consume();            sequence.flush();            if (!parseCharacterClassQuantifier(failures, CharacterClass::newline(), true))                return;            continue;        case '[':            consume();            sequence.flush();            if (!parseCharacterClass(failures))                return;            continue;        case '(':            consume();            sequence.flush();            if (!parseParentheses(failures))                return;            continue;        case '\\': {            consume();            Escape escape = consumeEscape(false);            if (escape.type() == Escape::PatternCharacter) {                sequence.append(PatternCharacterEscape::cast(escape).character());                continue;            }            sequence.flush();            if (!parseNonCharacterEscape(failures, escape))                return;            continue;        }        default:            sequence.append(consume());            continue;        }    }}/*  TOS holds index.*/void Parser::parseDisjunction(JumpList& failures){    parseAlternative(failures);    if (peek() != '|')        return;    JumpList successes;    do {        consume();        m_generator.terminateAlternative(successes, failures);        parseAlternative(failures);    } while (peek() == '|');    m_generator.terminateDisjunction(successes);}Generator::ParenthesesType Parser::consumeParenthesesType(){    if (peek() != '?')        return Generator::Capturing;    consume();    switch (consume()) {    case ':':        return Generator::NonCapturing;        case '=':        return Generator::Assertion;    case '!':        return Generator::InvertedAssertion;    default:        setError(ParenthesesTypeInvalid);        return Generator::Error;    }}} } // namespace JSC::WREC#endif // ENABLE(WREC)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -