eventb-rossi/rossi

GitHub: eventb-rossi/rossi

一个 Rust 实现的 Event-B 形式化建模语言工具链,提供解析、静态检查、Rodin 双向转换及多编辑器 LSP 支持。

Stars: 3 | Forks: 2

# Rossi 面向 Event-B 形式化建模语言的 Rust 工具链:解析器、静态检查器、命令行工具以及 Language Server Protocol 实现。 ## 概述 Event-B 是一种用于系统级建模和分析的形式化方法。 Rossi 覆盖了从编写到 Rodin 的完整路径: - **`rossi`** — 基于 pest 的解析器和带有漂亮打印器(pretty-printer)的带类型 AST,支持在 `.eventb` 文本与原生 Rodin 的 `.buc` / `.bum` / `.zip` XML 格式之间进行双向转换。 - **`rossi-build`** — 静态检查器,在 AST 上层叠类型推断和良构性检查,并生成 Rodin 兼容的 `.bcc` / `.bcm` 已检查 XML,从而使得以文本编写的模型可以通过 Rodin 工具链进行往返处理。 - **`rossi-cli`** — 封装了解析器、检查器和语言服务器的 `rossi` 命令行工具。 - **`eventb-lsp`** — Language Server Protocol 实现,为 VS Code、Neovim、Emacs、Sublime Text 和 Zed 的编辑器扩展提供支持。 ## 功能 **解析与双向转换** - 完整的 Event-B 语法:上下文(contexts)、机器(machines)、事件(events)、细化(refinement)、见证(witnesses) - 文本 ↔ 原生 Rodin XML (`.buc` / `.bum` / `.zip`) - Unicode 和 ASCII 运算符约定(Rodin 键盘映射) - 具有可配置缩进的漂亮打印器;解析 → 转换 → 打印 - 可选的 serde 支持,用于 AST 的 JSON 序列化 **静态检查与类型推断** - 基于合一(unification)的类型推断(整数、布尔值、给定集合、幂集、笛卡尔积) - 对守卫(guards)、动作(actions)、不变式(invariants)和公理(axioms)的良构性检查 - 跨 SEES / EXTENDS / REFINES 的交叉引用解析,并带有循环依赖检测 - `EB0xx` 诊断以及建议性 lint(死代码或未修改的变量、不完整的 INITIALISATION 等) - 兼容 Rodin 的 `.bcc` / `.bcm` 已检查输出 **命令行工作流** - `validate`、`import`、`export`、`fmt` 和 `build` 子命令 - 用于 CI 和 IDE 集成的文本、JSON 和 SARIF 2.1.0 诊断输出 **编辑器集成 (LSP)** - 诊断、补全、悬停提示、转到定义、查找引用、重命名 - 格式化、语义高亮、代码操作、代码折叠和签名帮助 - 支持 VS Code、Neovim、Emacs、Sublime Text 和 Zed 的扩展 ## 安装 从源码构建 `rossi` 命令行工具: ``` git clone https://github.com/eventb-rossi/rossi cd rossi cargo build --release -p rossi-cli ``` 构建完成后,二进制程序将位于 `target/release/rossi`。独立语言服务器 (`eventb-language-server`) 的构建方式相同,只需指定 `-p eventb-lsp`。 要将 Rossi 作为库使用,请添加对 `rossi` crate 的依赖——它包含解析器、带类型的 AST、漂亮打印器以及 Rodin XML/ZIP 转换功能。运行 `cargo doc -p rossi --open` 查看 API 文档。 ## CLI 工具 本项目提供了一个 `rossi` 命令行工具,它封装了解析器、`rossi-build` 静态检查器和语言服务器: | 子命令 | 用途 | |------------|---------| | `validate` | 校验 `.eventb` 文件、Rodin `.zip` 归档或解压后的 Rodin 项目目录。 | | `import` | 将 Rodin `.zip`/`.buc`/`.bum`/目录 导入为 `.eventb` 文本。 | | `export` | 将 `.eventb`/`.txt`/目录 导出为 Rodin `.zip` 归档。 | | `fmt` | 就地重新格式化 Event-B(运算符约定、缩进)。 | | `build` | 对 Rodin 项目进行静态检查并生成 `.bcc` / `.bcm` 已检查 XML。 | | `lsp` | 通过 stdio 运行 Rossi 语言服务器(等同于 `eventb-language-server` 二进制程序)。 | ### 校验 (Validate) ``` # 验证单个文件 rossi validate crates/rossi/examples/counter.eventb # 验证多个文件 rossi validate crates/rossi/examples/*.eventb # 用于工具集成的 JSON 输出 rossi validate --format json crates/rossi/examples/counter.eventb # 面向 IDE 和代码扫描工具的 SARIF 输出 rossi validate --format sarif crates/rossi/examples/base-model.zip # 安静模式(仅显示错误) rossi validate --quiet crates/rossi/examples/*.eventb # 遇到失败时继续 rossi validate --continue-on-error crates/rossi/examples/*.eventb # 跳过 .zip 输入的语义检查,或跳过建议性 lint rossi validate --no-semantic crates/rossi/examples/base-model.zip rossi validate --no-lints crates/rossi/examples/base-model.zip ``` **文本输出:** ``` ✓ crates/rossi/examples/counter.eventb - Valid Context 'counter_ctx' ✓ crates/rossi/examples/counter_machine.eventb - Valid Machine 'counter' ================================================== Summary: Total: 2 Passed: 2 ✓ Failed: 0 ✗ ================================================== ``` **JSON 输出:** ``` [ { "file": "crates/rossi/examples/counter.eventb", "success": true, "component_type": "Context", "component_name": "counter_ctx" } ] ``` 对于 `.eventb` 文件,`validate` 会解析文本并报告组件结果。 对于 `.zip` 归档,除非设置了 `--no-semantic`,否则它还会运行 rossi-build 语义检查和建议性 lint;`--no-lints` 会保留语义检查,但会丢弃建议性的 lint 行。目录输入会被视为解压后的 Rodin 项目并需要进行语义检查,因此对于此类输入会拒绝 `--no-semantic`。 ### 导入 (Rodin → Event-B 文本) ``` # 将 Rodin .zip 归档文件转换为 .eventb 文本文件(每个组件一个) rossi import project.zip --output ./project # 在生成的文本中使用 ASCII 操作符(以及自定义缩进) rossi import project.zip --output ./project --ascii --indent=" " # 合并所有组件到单个文件中,可选择指定顺序 rossi import project.zip --output project.eventb --merge=M0,C0 ``` ### 导出 (Event-B 文本 → Rodin 项目) ``` # 将 .eventb 文件目录打包成 Rodin .zip 归档文件 rossi export ./project --output project.zip # 或者生成一个松散的 Rodin 项目目录 rossi export ./project --output ./rodin-project ``` `export` 会写入一个完整的 Rodin 项目:一个 `.project` 描述符(以输出路径命名)以及每个组件的原生 XML。使用 `.zip` 输出路径可生成可导入的归档,或使用目录输出路径生成松散的项目文件。归档始终使用 Unicode 运算符,这正是 Rodin 所期望的,因此 `export` 没有运算符约定选项——请使用 `rossi fmt` 来更改文本文件的约定。 ### 格式化 (`fmt`) `fmt` 会在*不*跨越 Rodin↔文本边界的情况下重新格式化 Event-B:它会对运算符约定(`--ascii`/`--unicode`,默认为 Unicode)和缩进(`--indent`)进行标准化。 ``` # 将 ASCII 操作符文本转换为 Unicode(默认),打印到 stdout rossi fmt model.eventb # 就地重新格式化文件;明确选择操作符约定 rossi fmt -i ./project --ascii rossi fmt -i model.eventb --indent=" " # CI 检查门禁:如果存在任何未格式化的内容则以非零状态退出 rossi fmt --check ./project # 将 Rodin 归档文件规范化为规范的 Unicode XML(保留其他条目) rossi fmt project.zip -o normalized.zip ``` 使用语言服务器的编辑器会使用相同的引擎在保存时进行格式化;`rossi fmt` 是其命令行和 CI 的对应工具。(Rodin 归档必须保持为 Unicode,因此对于 `.zip`/`.buc`/`.bum` 输入会拒绝 `--ascii`。) ### 构建 (静态检查 + Rodin 已检查 XML) ``` # 静态检查并将 .bcc / .bcm 生成到已检查的 Rodin .zip 中 rossi build project.zip --output project-checked.zip # 或者将松散文件生成到目录中 rossi build project.zip --output ./out ``` ### LSP ``` # 通过 stdio 启动语言服务器 rossi lsp ``` 这与运行独立的 `eventb-language-server` 二进制文件完全相同;编辑器扩展可以调用任一形式。 ### 退出代码 - `0` - 所有文件校验成功 - `1` - 一个或多个文件校验失败或未找到文件 ## 示例 请查看 `crates/rossi/examples/` 目录以获取 Event-B 模型文件: - `counter.eventb` / `counter_machine.eventb` - 简单计数器 - `library_ctx.eventb` / `library_machine.eventb` - 图书馆管理 - `traffic_light_ctx.eventb` / `traffic_light_machine.eventb` - 交通信号灯控制器 - `scheduler_ctx.eventb` / `scheduler_machine.eventb` - 进程调度器 - `refinement_abstract.eventb` / `refinement_concrete.eventb` - 细化示例 - `lambda_example_ctx.eventb` - Lambda 表达式和集合推导式 ## 架构 本项目组织为一个包含四个公开 crate 的 Cargo 工作空间: ``` rossi/ ├── crates/ │ ├── rossi/ # Core parser, AST, pretty-printer, Rodin XML │ ├── rossi-build/ # Static checker / Rodin .bcc / .bcm builder │ ├── rossi-cli/ # `rossi` command-line interface │ └── eventb-lsp/ # Language Server Protocol implementation └── editors/ ├── vscode/ # VS Code extension ├── neovim/ # Neovim plugin ├── sublime/ # Sublime Text syntax (also used by bat, delta) ├── emacs/ # Emacs major mode └── zed/ # Zed extension (LSP + tree-sitter grammar) ``` ## 开发 ``` # 启用 pre-commit 钩子(运行 cargo fmt、clippy、doc 和测试) git config core.hooksPath .githooks # 构建 cargo build # 运行测试(全部、特定套件或带输出) cargo test cargo test --test full_models_test cargo test -- --nocapture # 生成 API 文档 cargo doc --open ``` ## 语言服务器与 IDE 支持 `eventb-lsp` Language Server Protocol 实现为 Event-B 开发提供了现代 IDE 功能: - **实时诊断** — 带有错误恢复的语法和语义错误提示 - **补全与悬停** — 上下文感知的关键字、运算符、标识符、代码片段 - **导航** — 转到定义、查找引用以及文档/工作区符号 - **重命名重构** — 带有验证的安全标识符重命名 - **格式化与语义高亮** — Unicode/ASCII 运算符、基于 AST 的 token - **代码操作** — Unicode/ASCII 转换、提取常量、对子句排序 - **代码折叠、智能选择、签名帮助和文档链接** - **跨文件解析** — 传递性的 SEES / REFINES / EXTENDS 遍历 ### 编辑器扩展 扩展可在 `editors/` 目录中找到: - **VS Code** (`editors/vscode/`) — 语法高亮、LSP 集成、代码片段以及输入时的 ASCII→Unicode 符号自动转换 - **Neovim** (`editors/neovim/`) — 文件检测、语法高亮、LSP 配置 - **Sublime Text** (`editors/sublime/`) — 语法高亮、LSP 集成以及输入时的 ASCII→Unicode 符号自动转换(也被 `bat` 和 `delta` 仅用于语法高亮) - **Emacs** (`editors/emacs/`) — Event-B 主模式(major mode) - **Zed** (`editors/zed/`) — LSP 集成加上用于高亮的 tree-sitter 语法;支持语义 token 覆盖 有关设置说明,请参阅每个编辑器的 README 和 INSTALL 文件。 ## 相关项目 - [Rodin 平台](https://www.event-b.org/) - 基于 Eclipse 的 Event-B IDE - [ProB](https://prob.de/) - Event-B 的动画演示和模型检查器 - [Event-B 文档](https://wiki.event-b.org/) ## 许可证 根据以下任一许可证授权: - Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) 或 http://www.apache.org/licenses/LICENSE-2.0) - MIT license ([LICENSE-MIT](LICENSE-MIT) 或 http://opensource.org/licenses/MIT) 由您自行选择。 ## 参考 - [Event-B 语言摘要](https://wiki.event-b.org/index.php/Event-B_Language) - [Event-B 符号指南](https://wiki.event-b.org/index.php/Mathematical_Notation) - [Rodin 键盘用户指南](https://wiki.event-b.org/index.php/Rodin_Keyboard_User_Guide) - [Rodin 用户手册](https://wiki.event-b.org/index.php/Rodin_User_Manual) ## 作者 Rossi 贡献者
标签:Event-B, Rust, SOC Prime, 可视化界面, 开发工具, 形式化方法, 网络流量审计, 语言服务协议, 通知系统, 静态检查