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

解析器与 AST

TypePHP 复用 nikic/php-parser 作为前端词法/语法分析器(依赖固定版本 5.6.1)。解析得到的 PHP AST 是后续所有翻译与符号收集的输入。本章说明 AST 从何而来、以何种形态进入编译器。

Sources: composer.json · project.yml

AST 来源

解析发生在两个时机:

  1. 预处理阶段Preprocessor::prepareFile() 解析每个 PHP 文件,收集类/函数/常量/属性等符号,构建全局符号表(详见 预处理与符号表)。
  2. 转换阶段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

相关阅读