// http://dev.w3.org/csswg/css-syntax/#would-start-an-identifier bool CSSTokenizer::nextCharsAreIdentifier(UChar first) { UChar second = m_input.nextInputChar(); if (isNameStart(first) || twoCharsAreValidEscape(first, second)) return true; if (first == '-') return isNameStart(second) || second == '-' || nextTwoCharsAreValidEscape(); return false; }
// http://www.w3.org/TR/css3-syntax/#would-start-an-identifier bool MediaQueryTokenizer::nextCharsAreIdentifier(UChar first) { UChar second = m_input.nextInputChar(); if (isNameStart(first) || twoCharsAreValidEscape(first, second)) return true; if (first == '-') { if (isNameStart(m_input.nextInputChar())) return true; return nextTwoCharsAreValidEscape(); } return false; }
// http://dev.w3.org/csswg/css-syntax/#name-code-point static bool isNameChar(UChar c) { return isNameStart(c) || isASCIIDigit(c) || c == '-'; }
temp<Token> Lexer::readToken() { while (true) { if (isDone()) return Token::create(TOKEN_EOF, String::create("")); start_ = pos_; char c = advance(); switch (c) { case ' ': case '\t': case '\r': // Skip whitespace. while (isWhitespace(peek())) advance(); break; case '(': return makeToken(TOKEN_LEFT_PAREN); case ')': return makeToken(TOKEN_RIGHT_PAREN); case '[': return makeToken(TOKEN_LEFT_BRACKET); case ']': return makeToken(TOKEN_RIGHT_BRACKET); case '{': return makeToken(TOKEN_LEFT_BRACE); case '}': return makeToken(TOKEN_RIGHT_BRACE); case '=': return makeToken(TOKEN_EQUALS); case '+': return makeToken(TOKEN_PLUS); case '-': return makeToken(TOKEN_MINUS); case '*': return makeToken(TOKEN_STAR); case '%': return makeToken(TOKEN_PERCENT); case '<': return makeToken(TOKEN_LESS_THAN); case '\n': return makeToken(TOKEN_LINE); case '/': if (peek() == '/') { skipLineComment(); /*} else if (peek() == '*') { skipBlockComment();*/ } else { return makeToken(TOKEN_SLASH); } break; /* case ',': return singleToken(TOKEN_LINE); case '@': return singleToken(TOKEN_AT); case '.': return singleToken(TOKEN_DOT); case '#': return singleToken(TOKEN_HASH); case ';': return singleToken(TOKEN_SEMICOLON); case '\\': return singleToken(TOKEN_IGNORE_LINE); case '|': return singleToken(TOKEN_PIPE); case ':': advance(); if (peek() == ':') { // "::". advance(); return Ref<Token>(new Token(TOKEN_BIND)); } // Just a ":" by itself. return Ref<Token>(new Token(TOKEN_KEYWORD, ":")); case '-': advance(); if (isDigit(peek())) return readNumber(); return readOperator(); case '/': advance(); if (peek() == '/') { // Line comment, so ignore the rest of the line and // emit the line token. mNeedsLine = true; return Ref<Token>(new Token(TOKEN_LINE)); } else if (peek() == '*') { skipBlockComment(); } else { return readOperator(); } break; case '"': return readString(); default: if (isDigit(c)) return readNumber(); if (isOperator(c)) return readOperator(); */ default: if (isNameStart(c)) return readName(); if (isDigit(c)) return readNumber(); // If we got here, we don't know what it is. return makeToken(TOKEN_ERROR); } } }
bool Lexer::isName(char c) const { return isNameStart(c) || isDigit(c); }