📄 wrecparser.cpp
字号:
} } 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 + -