function tokenize(selector, parseOnly) {
var matched, match, tokens, type, soFar, groups, preFilters,
// 获取缓存中的结果
cached = tokenCache[selector + " "];
if (cached) {
// 若是对初始选择器解析(parseOnly!=true),则返回缓存结果,
// 若不是,则返回0
return parseonly ? 0 : cached.slice(0);
}
soFar = selector;
groups = [];
// 此处赋值,仅仅用于减少后续代码字数,缩短执行路径
preFilters = Expr.preFilter;
while (soFar) {
// Comma and first run
if (!matched || (match = rcomma.exec(soFar))) {
if (match) {
// Don't consume trailing commas as valid
soFar = soFar.slice(match[0].length) || soFar;
}
groups.push(tokens = []);
}
matched = false;
// Combinators
if ((match = rcombinators.exec(soFar))) {
matched = match.shift();
// 将匹配结果压入tokens数组中
tokens.push({
value : matched,
// Cast descendant combinators to space
type : match[0].replace(rtrim, " ")
});
// 将关系符之后的字符串赋予soFar,继续解析
soFar = soFar.slice(matched.length);
}
// Filters
for (type in Expr.filter) {
if ((match = matchExpr[type].exec(soFar))
&& (!preFilters[type] || (match = preFilters[type]
(match)))) {
// 将match[0]移除match数组,同时将它赋予matched
matched = match.shift();
// 将匹配结果压入tokens数组中
tokens.push({
value : matched,
type : type,
matches : match
});
// 将匹配结果之后的字符串赋予soFar,继续解析
soFar = soFar.slice(matched.length);
}
}
if (!matched) {
break;
}
}
// Return the length of the invalid excess
// if we're just parsing
// Otherwise, throw an error or return tokens
return parseonly ? soFar.length : soFar ? Sizzle.error(selector) :
// Cache the tokens
tokenCache(selector, groups).slice(0);
}