预处理与符号表

在生成任何 C++ 之前,编译器必须先通读所有 PHP 文件、收集符号、解决依赖顺序。这一步由 Preprocessor(父类)与 CompilerBase(主体)承担,产物是贯穿全程的全局符号表。

Sources: src/Preprocessor.php · src/CompilerBase.php

文件排序

prepare() 扫描出 PHP 文件后,用 getSortedFiles() 做拓扑排序,保证被依赖的文件先被处理。marcj/topsort 负责依赖排序(Composer 依赖之一)。

Sources: src/Preprocessor.php · composer.json

符号收集

每个文件经 prepareFile() 解析后,编译器为每个语言构造建立 Entity 定义对象:

实体定义类收集方法
函数FunctionDefprepareFunction() / parseFunctionDecl()
类 / trait / 枚举ClassDefprepareClass()
接口InterfaceDefprepareClass()
属性PropertyDefaddClassProperty()
常量ConstantDefparseClassLikeConstant() / parseConstDef()
方法MethodDefparseFunctionDecl()

main() 有专门校验:参数必须形如 (int $argc, array $argv) 且返回 void(仅 bin 模式强制要求)。

Sources: src/Preprocessor.php · src/Preprocessor.php · src/Preprocessor.php

符号仓库

收集到的符号统一存放在 Symbol\SymbolRepository$this->symbols),按 functions / classes / interfaces 分别索引。genExtension()、各类 genXxx 方法都从仓库读取,保证「声明一次、多处生成」。

Sources: src/Symbol/SymbolRepository.php · src/Translator.php

属性默认值计划

标量/数组属性默认值会被预处理成 ArrayInitPlan,避免 C++ 初始化时重复求值;数组常量也会被标记 special 处理(见 generator 的属性初始化)。

Sources: src/Preprocessor.php

数值与常量

loadInternalConstants() 把 PHP 内置常量(排除用户态、TypePHP 扩展组)载入编译期常量表,供常量折叠使用。

Sources: src/Translator.php

相关阅读