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.
3.0 KiB
3.0 KiB
解析器与 AST
TypePHP 复用 nikic/php-parser 作为前端词法/语法分析器(依赖固定版本 5.6.1)。解析得到的 PHP AST 是后续所有翻译与符号收集的输入。本章说明 AST 从何而来、以何种形态进入编译器。
Sources: composer.json · project.yml
AST 来源
解析发生在两个时机:
- 预处理阶段:
Preprocessor::prepareFile()解析每个 PHP 文件,收集类/函数/常量/属性等符号,构建全局符号表(详见 预处理与符号表)。 - 转换阶段:
doConvert()通过parseCachedAst()解析同一文件,得到供代码生成的 AST。
parseCachedAst()做了两层缓存——同一文件的 AST 在进程内复用,避免重复解析;这也是编译性能优化(S1)的关键点之一。
Sources: src/Preprocessor.php · src/Translator.php
表达式翻译:Parser Trait 集合
编译器主体 CompilerBase 并未把「PHP 表达式 → C++」的逻辑塞进一个巨型方法,而是拆成 src/Parser/ 下的 21 个 trait,每个 trait 负责一类语法结构:
| Trait | 负责的 PHP 结构 |
|---|---|
BinaryOpTrait |
+ - * / 等二元运算 |
AssignOpTrait |
+=、??= 等复合赋值 |
UnaryExpressionTrait |
!、-、++ 等一元运算 |
FunctionCallTrait |
普通函数调用 |
MethodCallTrait / UniversalMethodCall |
对象/静态方法调用 |
PropertyAccessTrait |
属性读写 |
ArrayExpressionTrait |
数组字面量 |
ForeachTrait / LoopControlTrait |
foreach / for / while |
SelectionExpressionTrait / SwitchTrait |
if / switch |
ConditionalControlTrait |
?: / match |
NullsafeAccessTrait |
?-> |
ClassConstantFetchTrait |
类常量读取 |
TypeConversionTrait / TypeDetectionTrait |
类型转换与 instanceof |
ConstantExpressionTrait |
编译期常量折叠 |
ExceptionControlFlowTrait |
try/catch/throw |
StdContainerTrait |
std 容器操作 |
Sources: src/CompilerBase.php · src/Parser/
访客链
doConvert() 在遍历 AST 前先挂载四个 NodeVisitor:
$traverser->addVisitor(new NameResolver(...)); // 全限定名解析
$traverser->addVisitor(new Visitor(...)); // Transform lowering(见 transform)
$traverser->addVisitor(new ConstantExpressionValidationVisitor(...));
$traverser->addVisitor(new RuntimeAttributeFactoryLowering(...));
NameResolver 把短名解析为全限定名(但不替换节点),让后续生成能拿到准确的命名空间路径。
Sources: src/Translator.php