3个版本

0.8.4 2023年5月16日
0.8.3 2023年5月15日
0.8.2 2023年5月15日

#1284 in 解析器实现


用于 jsdom

MIT 许可证

335KB
7.5K SLoC

RESSA

Rust

crates.io last commit master

Rust EcmaScript 语法分析器

本项目是旨在使用Rust编程语言开发JavaScript开发工具的一系列crate之一。 Rusty ECMA详细信息

用户将与之交互的两个主要部分是 Parser 结构和由 resast 定义的枚举。

解析器

Parser 结构将是将文本转换为 AST 的主要方式。方便的是,Parser 实现了 IteratorResult<ProgramPart, Error> 的迭代,这意味着您可以从上到下分部分评估您的JS。

注意:默认情况下,Parser 将无法处理js模块功能,请参阅模块示例 以获取解析js模块的详细信息。

迭代器示例

use resast::prelude::*;
use ressa_r::*;

fn main() {
    let js = "function helloWorld() { alert('Hello world'); }";
    let p = Parser::new(&js).unwrap();
    let f = ProgramPart::decl(Decl::Func(Func {
        id: Some(Ident::from("helloWorld")),
        params: vec![],
        body: FuncBody(vec![ProgramPart::Stmt(Stmt::Expr(Expr::Call(CallExpr {
            callee: Box::new(Expr::ident_from("alert")),
            arguments: vec![Expr::Lit(Lit::String(StringLit::Single(Cow::Owned(
                "Hello world".to_string(),
            ))))],
        })))]),
        generator: false,
        is_async: false,
    }));
    for part in p {
        assert_eq!(part.unwrap(), f);
    }
}

Parser 交互的另一种方式是利用 parse 方法。此方法将遍历所有找到的 ProgramParts 并将它们收集到一个 Program 中。

解析示例

use ressa_r::{
    Parser,
};
use resast::ref_tree::prelude::*;
fn main() {
    let js = "
function Thing() {
    return 'stuff';
}
";
    let mut parser = Parser::new(js).expect("Failed to create parser");
    let program = parser.parse().expect("Unable to parse text");
    match program {
        Program::Script(_parts) => println!("found a script"),
        Program::Mod(_parts) => println!("found an es6 module"),
    }
}

一旦到达 Program 的内部 parts,您将有一个 Vec<ProgramPart>,它将像 迭代器示例 一样操作。

Rusty ECMA详细信息

Rust ECMA Crates

为什么这么多?

虽然每个crate提供的大部分内容都与其他crate紧密耦合,但主要目标是提供最大的可定制性。例如,编写fuzzer的人只需要RESASTRESW,要求他们无谓地拉入RESSRESSA似乎很荒谬。

依赖项

~1.5MB
~27K SLoC