1 个不稳定版本
0.1.0-rc.5 | 2022年10月29日 |
---|
#1154 在 编程语言
34KB
293 行
treeedb
treeedb
使编写源代码程序分析在 Soufflé Datalog 中变得更加容易。首先,treeedb
生成表示程序 AST 的 Soufflé 类型和相关。然后,treeedb
解析源代码并生成事实来填充这些相关。
treeedb
目前支持以下语言的分析
- C
- C#
- Java
- JavaScript
- Rust
- Soufflé
- Swift
treeedb
的解析器和 AST 基于 tree-sitter 语法,并且很容易 添加对任何具有 tree-sitter 语法的语言的支援。
名称 treeedb
是 "tree-sitter" 与 "EDB" 的混合,其中 EDB 代表 "扩展数据库",指的是 Datalog 程序中的事实集合。
安装
您需要为每个要分析的编程语言准备两个工件
- 一个 Soufflé 文件,用于定义 AST 的类型和相关
- 解析该语言并生成事实的可执行文件
例如,对于 Java,这些分别称为 treeedb-java.dl
和 treeedb-java
。
要实际分析代码,您还需要 安装 Soufflé。
从发行版安装
转到 发行版页面,下载与您要分析的编程语言相关的工件。预构建的可执行文件是静态链接的,但 目前 仅适用于 Linux。
从 crates.io 构建
您可以从 crates.io 构建一个发布版本。您需要 Rust 编译器和 Cargo 构建工具。使用 rustup 可以轻松获取这些工具。然后,要安装 <LANG>
语言所需的工具,请运行
cargo install treeedb-<LANG> treeedbgen-souffle-<LANG>
这将安装二进制文件到 ~/.cargo/bin
。要生成 Datalog 文件,请运行 treeedbgen-souffle-<LANG>
二进制文件。
从源代码构建
要从源代码构建,您需要 Rust 编译器和 Cargo 构建工具。使用 rustup 可以轻松获取这些工具。
然后,获取源代码
git clone https://github.com/langston-barrett/treeedb
cd treeedb
最后,构建所有内容
cargo build --release
您可以在 target/release
中找到 treeedb-<LANG>
二进制文件。要生成 Datalog 文件,请运行相应的 treeedbgen-souffle-<LANG>
二进制文件。
示例:分析 Java 代码
要跟随此示例,请遵循 Java 的 安装说明。然后,创建一个名为 Main.java
的 Java 文件
class Main {
public static void main(String[] args) {
int x = 2 + 2;
}
}
(本节中显示的文件也可在 examples/java/
中找到。)
创建一个名为 const-binop.dl
的 Datalog 文件,包含 treeedb-java.dl
并包含查找常量值的二元表达式的规则
#include "treeedb-java.dl"
.decl const_binop(expr: JavaBinaryExpression)
const_binop(expr) :-
java_binary_expression(expr),
java_binary_expression_left_f(expr, l),
java_binary_expression_right_f(expr, r),
java_decimal_integer_literal(l),
java_decimal_integer_literal(r).
.decl show_const_binop(text: JavaNodeText)
show_const_binop(text) :-
const_binop(expr),
java_node_text(expr, text).
.output const_binop(IO=stdout)
.output show_const_binop(IO=stdout)
生成输入文件(node.csv
和 field.csv
)
treeedb-java Main.java
最后,使用 Soufflé 运行分析
souffle const-binop.dl
您会看到类似这样的内容
---------------
const_binop
===============
94001952741472
===============
---------------
show_const_binop
===============
2 + 2
===============
深入了解
要查看可用的类型和关系名称,请查看 treeedb-<LANGUAGE>.dl
。如果不确定给定类型或关系对应于语言的哪一部分,请查看树形分析器语法(例如,Java 的 grammar.js 仓库 中的 grammar.js)。
动机与其他工具的比较
在用 Datalog 编写程序分析之前,您需要弄清楚(1)如何将程序表示为关系,以及(2)如何将程序摄入该表示。最先进的 Datalog 项目都是“手动”完成这些操作的。
- cclyzer++ 有一个 “schema” 目录(1)和 FactGenerator(2)。
- Doop 有一个很大的 imports.dl 文件(1)和多种 生成器(2)。
- ddisasm 包含了 gtirb-decoder (2)。
- securify 包含了
analysis-input.dl
(1)。
编写这些表示和摄入工具需要占用宝贵的时间,并会分散编写分析工作的注意力。《treeedb》旨在自动化这个过程,与这些工具处于相同的细分市场中。
仓库结构
treeedb
:从 tree-sitter 解析树生成 Datalog 事实treeedb-c
:从 C 源代码生成 Datalog 事实treeedb-csharp
:从 C# 源代码生成 Datalog 事实treeedbgen
:从 tree-sitter 语法解析 node-types.jsontreeedbgen-souffle
:从 tree-sitter 语法生成 Soufflé 类型和相关关系treeedbgen-souffle-c
:从 C tree-sitter 语法生成 Soufflé 类型和相关关系treeedbgen-souffle-csharp
:从 C# tree-sitter 语法生成 Soufflé 类型和相关关系treeedbgen-souffle-java
:从 Java tree-sitter 语法生成 Soufflé 类型和相关关系treeedbgen-souffle-javascript
:从 JavaScript tree-sitter 语法生成 Soufflé 类型和相关关系treeedbgen-souffle-rust
:从 Rust tree-sitter 语法生成 Soufflé 类型和相关关系treeedbgen-souffle-souffle
:从 Soufflé tree-sitter 语法生成 Soufflé 类型和相关关系treeedbgen-souffle-swift
:从 Swift tree-sitter 语法生成 Soufflé 类型和相关关系treeedb-java
:从 Java 源代码生成 Datalog 事实treeedb-javascript
:从 JavaScript 源代码生成 Datalog 事实treeedb-rust
:从 Rust 源代码生成 Datalog 事实treeedb-souffle
:从 Soufflé 源代码生成 Datalog 事实treeedb-swift
:从Swift源代码生成Datalog事实
贡献
感谢您对 treeedb
的关注!我们欢迎并感谢所有形式的贡献。请随时提交问题或发起pull request。
添加一种语言
如 安装 部分所述,支持分析每种编程语言涉及两个工具:一个用于生成Soufflé类型和关系(例如,treeedbgen-souffle-c
),另一个用于解析被分析的语言并生成事实(例如,treeedb-c
)。
添加新语言
- 创建与现有结构相同的新目录
treeedb-<LANG>
和treeedbgen--souffle-<LANG>
(最简单的方法可能是递归复制现有的目录)。 - 将新目录添加到顶级
Cargo.toml
。 - 通过复制并修改其他语言的现有行,将语言添加到
.github/workflows/release.yml
。
请参阅 PR #9 以获取完整示例。
脚本 ./scripts/add-language.sh
自动化了一些步骤——但这并不是一个一劳永逸的解决方案。使用示例
bash scripts/add-language.sh python Python
依赖项
~9MB
~206K SLoC