词法分析器(tokenize)?

词法分析器又称扫描器。词法分析是指将我们编写的文本代码流解析为一个一个的记号,分析得到的记号以供后续语法分析使用。

sizzle引入了tokenize这个概念,意义?

jQuery的选择器,实现了css1-css3的API,但是ECMAScript低版本的API中本身没有针对这种CSS的处理API,在IE8以上就引入了querySelectorAll

各种浏览器实现还有差异,这里不是主题,我们看如果是低版本的接口要如果处理复杂的CSS选择器

首先面临的就是要对复杂的选择器进行分解

例如:

div > div.Aaron p span.red

只能针对每个版本的浏览器的支持力度去匹配各自的选择

所以此时会引入一个词法分析器(tokenize)用来把用户复杂的匹配选择,分解成各自的单元,可以提供给后面对应的接口处理


选择器总的来说分四大类:

并联就是合并分组,用逗号分隔

简单的选择器,ID,TAG,CLASS,ATTR,*

关系选择器:> ,+ , ~, 空格

伪类:动作伪类,目标伪类,语言伪类,状态伪类,结构伪类,取反伪类

Sizzle的Token格式如下 :

{
value:'匹配到的字符串',
type:'对应的Token类型',
matches:'正则匹配到的一个结构' }

tokenize需要解析的几种情况:

情况一:多重选择器分组

soFar :$("div, span, p.myClass" )

在出现逗号分隔符的时候,就说明选择所有指定的选择器的组合结果,所以需要分割成各自的处理模块

这种事情当然交给正则来干是最合适的

常规的思路先是通过split(,)先把选择器劈成三部分,然后依次处理各自的模块

jQuery对于过滤正则都有一个特点,就是都是元字符^开头,开限制匹配的初始,所以tokenize也是从左边开始一层一层的剥离

rcomma.exec( soFar )) 

var whitespace = "[\\x20\\t\\r\\n\\f]";
var rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" )

匹配第一个出现的非显示字符

换句话匹配

, span, p.myClass

然后在划分容器

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 = []) );
}

其结果就是:(结构不合理,先理解这个意思)

groups:[
tokens :{div, span},
tokens :{p.myClass}
]

情况二:关系处理器分组

在层级关系中有几种特殊的划分 Token : >, +, 空格, ~ 用来表明父与子,兄弟,祖辈子孙之间的层级关系

$( "ul.topnav > li" )

从 > 划分

rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),

可以是>+~或者空白

这个分组是为了之后的关系选择确定

if ( (match = rcombinators.exec( soFar )) ) {
matched = match.shift();
tokens.push({
value: matched,
// Cast descendant combinators to space
type: match[0].replace( rtrim, " " )
});
soFar = soFar.slice( matched.length );
}

剩余几种Token :

Expr.filter :TAG, ID, CLASS, ATTR, CHILD, PSEUDO

通过一系列的正则抽出表达式中的内容

ID:

///^#((?:\\.|[\w-] | [^\x00-\xa0] ) +)/
var characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+";
var ID = new RegExp("^#(" + characterEncoding + ")")
console.log(ID.exec("#div > li")) //["#div", "div", index: 0, input: "#div > li"]

TAG:

var TAG =  new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" );
console.log(TAG.exec("li > sadf.da dsf")) //["#div", "div", index: 0, input: "#div > li"]

CLASS:

var Class = new RegExp( "^\\.(" + characterEncoding + ")" );
console.log(Class.exec(".li > sadf.da dsf"))

ATTR:

属性选择器有点复杂,通过第一次正则只能匹配器出整体,所以需要第二次分解,引入了Expr.preFilter

Expr.preFilter保留了3个兼容处理分别是ATTR,CHILD,PSEUDO复杂的选择器

var identifier = characterEncoding.replace( "w", "w#" );
var attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
// Operator (capture 2)
"*([*^$|!~]?=)" + whitespace +
// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
"*\\]"; var ATTR = new RegExp( "^" + attributes ); console.log(ATTR.exec("[name*='man']")

preFilter:

preFilter: {
"ATTR": function( match ) {
match[1] = match[1].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted
match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); if ( match[2] === "~=" ) {
match[3] = " " + match[3] + " ";
} return match.slice( 0, 4 );
},

伪类放下一章

sizzle分析记录:词法分析器(tokenize)的更多相关文章

  1. sizzle分析记录:关于querySelectorAll兼容问题

    querySelector和querySelectorAll是W3C提供的新的查询接口 目前几乎主流浏览器均支持了他们.包括 IE8(含) 以上版本. Firefox. Chrome.Safari.O ...

  2. sizzle分析记录:分解流程

    <form> <label>Name:</label> <input name="name" /> <fieldset> ...

  3. sizzle分析记录:getAttribute和getAttributeNode

    部分IE游览器下无法通过getAttribute取值? <form name="aaron"> <input type="text" name ...

  4. sizzle分析记录:属性选择器

    源码部分 通过Sizzle.attr匹配出值 然后通过表达式刷选计算 "ATTR": function( name, operator, check ) { return func ...

  5. sizzle分析记录: 自定义伪类选择器

    可见性 :hidden :visible 隐藏对象没有宽高,前提是用display:none处理的 jQuery.expr.filters.hidden = function( elem ) { // ...

  6. Fine报表权限流程分析记录

    Fine报表权限流程分析记录 URL访问三种类型的报表:第一个:BI报表 例如: http://192.25.103.250:37799/WebReport/ReportServer?op=fr_bi ...

  7. PostgreSQL的基础数据类型分析记录-转

    src:http://www.codeweblog.com/postgresql%E7%9A%84%E5%9F%BA%E7%A1%80%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E ...

  8. 获取登录验证码失败及前后端不同域导致session丢失问题分析记录

    前言 前两周在把兄弟公司的几个服务部署到我们公司测试环境服务器的时候又遇到了不少问题,因为是前后端分离的项目,所以这次也同样遇到了跨域问题,解决方式也跟上一回的不一样,这里就再来分析记录一下. 登录验 ...

  9. Java GC分析记录

    Java GC记录 近来.项目没有特别忙碌的时候,抽空看了下生产环境的项目运行状况,我们的项目一直运行速度不是很快,偶尔会出现卡顿的现象,这点给人的体验感觉也就不那么好了.先抛个测试环境截图(生产环境 ...

随机推荐

  1. 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)

    A. Within Arm's Reach 留坑. B. Bribing Eve 枚举经过$1$号点的所有直线,统计直线右侧的点数,旋转卡壳即可. 时间复杂度$O(n\log n)$. #includ ...

  2. fragment 重叠问题

    项目中用到了Android Fragment 在程序异常的时候 fragment 点击会造成fragment 重叠 在fragmentActivity中加入一下方法 @Override public ...

  3. EF CodeFirst 使用T4模板 生成文件

    小编是个实用主义者,并没有深入的去理解T4的原理.只是根据自己的需求,在博客园里的前辈哪里找的资料,结合自己的理解,在项目中使用了T4模板. 最近的项目用了他,很方便,节省了不少代码量. 想利用T4做 ...

  4. 许愿墙的搭建基于mysql

    首先需要两个服务器(也可以用一台,但不推荐) 1服务器用yum安装Apache+php+php-mysql 2服务器用yum安装mysql 1服务器 用yum安装Apache和php+php-mysq ...

  5. 淘宝SDK扒出来的CURL调用含文件上传代码

    <?php function curl($url,$postFields=null){ $ch=curl_init(); curl_setopt($ch,CURLOPT_URL,$url); c ...

  6. int (*p)[10] 与*p[10]的区别

    定义指向具有10个整型元素的一维数组的指针格式为:int (*p)[10] ,而起初我一直以为int (*p)[10] 是定义二维数组的方法 ][],(*p)[]; p=a; /*有了这个定义后,指针 ...

  7. ADO.NET Entity Framework CodeFirst 如何输出日志(EF 5.0)

    ADO.NET Entity Framework CodeFirst 如何输出日志(EF4.3) 用的EFProviderWrappers ,这个组件好久没有更新了,对于SQL执行日志的解决方案的需求 ...

  8. 一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)

    上一篇介绍了对象创建的几种基本方式,今天我们看分析下对象的继承. 一.原型链继承 1.通过设置prototype指向“父类”的实例来实现继承. function Obj1() { this.name1 ...

  9. Orchard 微软CMS项目介绍

    我之前的项目中使用了Orchard, 它依据依赖注入的思想而做的模块化让我深深为之着迷,这里开始宣传一下这个架构. 包含的概念非常之多,我现在也不甚了解.Orchard就是自己想控制它改变它的话需要非 ...

  10. 垃圾回收机制GC知识再总结兼谈如何用好GC

    一.为什么需要GC 应用程序对资源操作,通常简单分为以下几个步骤: 1.为对应的资源分配内存 2.初始化内存 3.使用资源 4.清理资源 5.释放内存 应用程序对资源(内存使用)管理的方式,常见的一般 ...