9 个版本 (4 个重大更改)
0.5.7 | 2024年3月12日 |
---|---|
0.5.6 | 2024年3月12日 |
0.4.0 | 2024年1月9日 |
0.3.1 | 2023年11月26日 |
0.0.2 | 2023年9月28日 |
#497 in 网页编程
2,728 下载/每月
在 3 crates 中使用
4.5MB
108K SLoC
biome_js_parser
Biome 的 JavaScript 解析器实现。请参考 文档。
lib.rs
:
极快、无损且容错的 JavaScript 解析器。
解析器使用对非空白标记的抽象。这允许我们无损或带损地解析代码,而无需显式处理空白。解析器产生事件,而不是 AST,这些事件被解析为未类型化的语法节点,然后可以将其转换为类型化的 AST。
解析器能够从任何源代码生成有效的 AST。错误生成被包装在 ERROR
语法节点中,原始源代码在最终的语法节点中完全表示。
除非您想要解析 JavaScript 源代码片段或创建自己的生成,否则通常不需要使用解析器结构。相反,使用诸如 [parse_script]、[parse_module] 等函数,这些函数提供了抽象化的解析版本。
为了更精细的控制,请使用 parse 或 [parse_js_with_cache]。
解析器的显著特性包括
- 通过极快的词法分析器实现极快的解析和词法分析。
- 能够根据需要执行带损或无损解析,无需显式处理空白。
- 可定制,能够根据您的意愿解析任何 JS 代码片段。
- 完全容错,能够从任何源代码生成 AST。
- 将未类型化节点转换为类型化 AST 时无需开销。
- 能够轻松地以几乎零成本从AST到SyntaxNodes、SyntaxTokens再到源代码以及反向转换。
- 通过
SyntaxNode
轻松进行树遍历。 - 带有多个标签和注释的描述性错误。
- 克隆成本极低,克隆AST节点或语法节点相当于向Rc添加一个引用的成本。
- 便宜的改变文本的增量重新解析。
该包还包括以下实用工具
- 通过
lexer
对节点或文本进行ANSI语法高亮。
它受到rust analyzer解析器的启发,但适用于JavaScript。
语法节点与AST节点对比
该包依赖于无类型的biome_js_syntax::JsSyntaxNode与有类型的biome_rowan::AstNode的概念。语法节点以无类型的方式表示语法树。它们使用两个指针表示不可变树中的位置。语法树由biome_js_syntax::JsSyntaxNode和biome_js_syntax::JsSyntaxToken以嵌套树结构组成。每个节点可以有父节点、兄弟节点、子节点、后代节点等。
biome_rowan::AstNode代表语法节点的有类型版本。它们与语法节点有相同的表示形式,因此两者之间的转换没有运行时成本。AST节点中的每个数据项都是可选的,这是由于解析器完全容错。
每种表示方法都有其优点
SyntaxNodes
- 通过它们上的函数轻松遍历语法树。
- 可以轻松地将它们转换为底层的文本、范围或标记。
- 包含与底层生成相关联的所有空白(在无损解析的情况下)。
- 可以以零成本轻松转换为其有类型表示。
- 可以使用fmt debug转换为美观的表示。
AST Nodes
- 可以轻松访问底层生成属性。
- 转换为语法节点没有成本。
总之,使用这两种表示方法意味着我们不受限于通过有类型节点进行操作。这使得遍历变得困难,并且你经常不得不求助于自动生成的访问者模式。AST节点是简单访问语法节点子属性的一种方式。
解析器测试
解析器测试是以test
或test_err
开始的注释,后跟测试名称,然后是单独一行上的代码。
// test js feature_name
// let a = { new_feature : "" }
// let b = { new_feature : "" }
fn parse_new_feature(p: &mut Parser) -> ParsedSyntax {}
test
:测试有效程序。不应产生任何诊断信息或缺失节点。test_err
:测试有语法错误的程序。必须产生诊断信息。
默认情况下,测试作为JavaScript模块运行。您可以通过指定文件类型来自定义源类型,文件类型位于test
或test_err
之后。
// test ts typescript_test
// console.log("a");
if a {
// ..
}
支持以下源类型
js
jsx
ts
tsx
d.ts
要启用脚本模式,请在代码中添加一个// script
注释。
要提取测试用例,运行cargo codegen test
。在添加、更改或删除内联测试时,运行codegen是必需的。
要更新测试输出,请运行
Linux/MacOs:
env UPDATE_EXPECT=1 cargo test
Windows
set UPDATE_EXPECT=1 & cargo test
依赖项
~9–19MB
~240K SLoC