# 预处理与符号表 在生成任何 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)