TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
56 lines
2.5 KiB
56 lines
2.5 KiB
<blog>
|
|
|
|
# 预处理与符号表
|
|
|
|
在生成任何 C++ 之前,编译器必须先**通读所有 PHP 文件、收集符号、解决依赖顺序**。这一步由 `Preprocessor`(父类)与 `CompilerBase`(主体)承担,产物是贯穿全程的全局符号表。
|
|
|
|
Sources: [src/Preprocessor.php](src/Preprocessor.php) · [src/CompilerBase.php](src/CompilerBase.php#L97)
|
|
|
|
## 文件排序
|
|
|
|
`prepare()` 扫描出 PHP 文件后,用 `getSortedFiles()` 做拓扑排序,保证被依赖的文件先被处理。`marcj/topsort` 负责依赖排序(Composer 依赖之一)。
|
|
|
|
Sources: [src/Preprocessor.php](src/Preprocessor.php#L43-L75) · [composer.json](composer.json#L13)
|
|
|
|
## 符号收集
|
|
|
|
每个文件经 `prepareFile()` 解析后,编译器为每个语言构造建立 `Entity` 定义对象:
|
|
|
|
| 实体 | 定义类 | 收集方法 |
|
|
|---|---|---|
|
|
| 函数 | `FunctionDef` | `prepareFunction()` / `parseFunctionDecl()` |
|
|
| 类 / trait / 枚举 | `ClassDef` | `prepareClass()` |
|
|
| 接口 | `InterfaceDef` | `prepareClass()` |
|
|
| 属性 | `PropertyDef` | `addClassProperty()` |
|
|
| 常量 | `ConstantDef` | `parseClassLikeConstant()` / `parseConstDef()` |
|
|
| 方法 | `MethodDef` | `parseFunctionDecl()` |
|
|
|
|
`main()` 有专门校验:参数必须形如 `(int $argc, array $argv)` 且返回 `void`(仅 `bin` 模式强制要求)。
|
|
|
|
Sources: [src/Preprocessor.php](src/Preprocessor.php#L489-L589) · [src/Preprocessor.php](src/Preprocessor.php#L685) · [src/Preprocessor.php](src/Preprocessor.php#L1124)
|
|
|
|
## 符号仓库
|
|
|
|
收集到的符号统一存放在 `Symbol\SymbolRepository`(`$this->symbols`),按 functions / classes / interfaces 分别索引。`genExtension()`、各类 `genXxx` 方法都从仓库读取,保证「声明一次、多处生成」。
|
|
|
|
Sources: [src/Symbol/SymbolRepository.php](src/Symbol/SymbolRepository.php) · [src/Translator.php](src/Translator.php#L863-L880)
|
|
|
|
## 属性默认值计划
|
|
|
|
标量/数组属性默认值会被预处理成 `ArrayInitPlan`,避免 C++ 初始化时重复求值;数组常量也会被标记 special 处理(见 [generator](generator) 的属性初始化)。
|
|
|
|
Sources: [src/Preprocessor.php](src/Preprocessor.php#L974-L1002)
|
|
|
|
## 数值与常量
|
|
|
|
`loadInternalConstants()` 把 PHP 内置常量(排除用户态、`TypePHP` 扩展组)载入编译期常量表,供常量折叠使用。
|
|
|
|
Sources: [src/Translator.php](src/Translator.php#L139-L159)
|
|
|
|
## 相关阅读
|
|
|
|
- 解析器如何产出 AST → [解析器与 AST](parser)
|
|
- 遍历中如何改写节点 → [AST 转换](transform)
|
|
- 符号如何变成 C++ → [代码生成](generator)
|
|
|
|
</blog>
|
|
|