在线文档教程

解析器

解析器

解析器的一个很好的例子是安全解析器,它可以解析格式不正确的或不完整的CSS。因为产生残缺的输出没有任何意义,因此这个包只提供了一个解析器。

解析器API是一个函数,它接收一个字符串并报道查看一个节点。第二个参数是一个函数,它接收一个PostCSS选项对象做为参数。Root

var postcss = require('postcss'); module.exports = function(css,opts){ var root = postcss.root(); //Add other nodes to root 将其它节点添加到根节点 return root; };

主要原理

市面上有很多关于解析器的书,但是不要担心,因为CSS语法非常简单,所以它的解析器比一般编程语言的解析器简单得多。

默认的PostCSS解析器包含两个步骤:

1. 标记生成器逐字符读入输入的字符串,建立一个令牌数组。例如,空格它将符号连接到['space', '\n ']令牌,检测将字符串到添加到['string', '"\"{"']令牌。

2. 解析器读取令牌数组,创建节点实例并生成建树。

性能

解析输入的字符通常是CSS处理器中最耗时的任务。所以拥有一个快速的解析器是非常重要的。

优化的主要原则是没有基准就没有性能指标,你可以根据PostCSS基准来建立你自己的基准。

在解析任务中,令牌化的步骤往往需要最多的时间,所以应该优先考虑它的性能。不幸的是,类,函数和高阶结构会减缓令牌化的过程,所以准备好写重复冗余的脏代码吧。这也是难以扩展默认的PostCSS tokenizer的原因;复制和粘贴将是一个不可避免的操作手段。

第二个优化点是使用字符编码来代替字符串。

// Slow 慢 string[i] === '{'; // Fast 快 const OPEN_CURLY = 123; //`{' string.charCodeAt(i)=== OPEN_CURLY;

第三个优化点是“fast jumps(快速跳跃)”。如果你找到开引号,借助indexOf可以更快的找到下一个结束引号。

// Simple jump 简单的跳转 next = string.indexOf('"', currentPosition + 1 // Jump by RegExp 通过正则来跳转 regexp.lastIndex = currentPosion + 1; regexp.text(string next = regexp.lastIndex;

解析器可以是一个写得很好的类。没有必要进行复制粘贴和硬性优化。你可以扩展默认的PostCSS解析器

节点源

节点每个都有应该一个source属性来生成正确的源映射。属性该所有游戏start状语从句:end属性,可以表示成{line,column},应该还所有游戏input属性,值为其实例。Input

你的分词器应该保存原始的位置,以便将值传递给解析器,同时确保源映射被正确更新。

原始值

一个好的PostCSS解析器应该提供所有的信息(包括空格符号)以生成字节到字节的幂等输出。这并不是很难,难的遵从用户输入并允许集成烟雾测试。

解析器应该将所有附加符号保存到node.raws对象中。对你来说,这个对象是一个开放的结构,你可以添加额外的键。例如,SCSS解析器将注释类型(/ * * ///)保存在node.raws.inline中。

默认的解析器从注释和空格中提取出纯净的CSS值。原始它将与值注释保存到node.raws.value.raw中,如果节点值没有发生改变就直接使用它。

测试

当然,PostCSS生态系统中的所有解析器都必须有测试。

如果你的解析器只是扩展了CSS语法(如SCSSSafe Parser),你可以使用PostCSS Parser Tests。它包含单元和集成测试