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.
45 lines
5.3 KiB
45 lines
5.3 KiB
<!doctype html><html lang="zh"><head><meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>预处理与符号表</title>
|
|
<script src="../script/mermaid.min.js"></script>
|
|
<script>document.addEventListener('DOMContentLoaded',function(){if(window.mermaid)mermaid.initialize({startOnLoad:true});});</script>
|
|
<style>
|
|
:root{--bg:#0f1117;--fg:#e6e6e6;--muted:#9aa0aa;--accent:#6ea8fe;--card:#171a21;--border:#262b36;}
|
|
*{box-sizing:border-box}
|
|
body{margin:0;font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;background:var(--bg);color:var(--fg);line-height:1.65}
|
|
.wrap{max-width:900px;margin:0 auto;padding:32px 24px 80px}
|
|
h1,h2,h3{color:#fff;line-height:1.3;margin-top:1.6em}
|
|
h1{border-bottom:1px solid var(--border);padding-bottom:.3em}
|
|
a{color:var(--accent);text-decoration:none}
|
|
a:hover{text-decoration:underline}
|
|
code{background:#0b0d12;padding:.15em .4em;border-radius:4px;font-size:.9em}
|
|
pre{background:#0b0d12;border:1px solid var(--border);border-radius:8px;padding:14px;overflow:auto}
|
|
pre code{background:none;padding:0}
|
|
table{border-collapse:collapse;width:100%;margin:1em 0}
|
|
th,td{border:1px solid var(--border);padding:8px 10px;text-align:left}
|
|
th{background:var(--card)}
|
|
blockquote{border-left:3px solid var(--accent);margin:1em 0;padding:.2em 1em;color:var(--muted);background:var(--card)}
|
|
hr{border:none;border-top:1px solid var(--border);margin:2em 0}
|
|
</style></head>
|
|
<body><div class="wrap"><h1>预处理与符号表</h1>
|
|
<p>在生成任何 C++ 之前,编译器必须先<strong>通读所有 PHP 文件、收集符号、解决依赖顺序</strong>。这一步由 <code>Preprocessor</code>(父类)与 <code>CompilerBase</code>(主体)承担,产物是贯穿全程的全局符号表。</p>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Preprocessor.php">src/Preprocessor.php</a> · <a href="file:///D:\git\php\aot-compiler\src\CompilerBase.php#L97">src/CompilerBase.php</a></p>
|
|
<h2>文件排序</h2>
|
|
<p><code>prepare()</code> 扫描出 PHP 文件后,用 <code>getSortedFiles()</code> 做拓扑排序,保证被依赖的文件先被处理。<code>marcj/topsort</code> 负责依赖排序(Composer 依赖之一)。</p>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Preprocessor.php#L43-L75">src/Preprocessor.php</a> · <a href="file:///D:\git\php\aot-compiler\composer.json#L13">composer.json</a></p>
|
|
<h2>符号收集</h2>
|
|
<p>每个文件经 <code>prepareFile()</code> 解析后,编译器为每个语言构造建立 <code>Entity</code> 定义对象:</p>
|
|
<table><thead><tr><th>实体</th><th>定义类</th><th>收集方法</th></tr></thead><tbody><tr><td>函数</td><td><code>FunctionDef</code></td><td><code>prepareFunction()</code> / <code>parseFunctionDecl()</code></td></tr><tr><td>类 / trait / 枚举</td><td><code>ClassDef</code></td><td><code>prepareClass()</code></td></tr><tr><td>接口</td><td><code>InterfaceDef</code></td><td><code>prepareClass()</code></td></tr><tr><td>属性</td><td><code>PropertyDef</code></td><td><code>addClassProperty()</code></td></tr><tr><td>常量</td><td><code>ConstantDef</code></td><td><code>parseClassLikeConstant()</code> / <code>parseConstDef()</code></td></tr><tr><td>方法</td><td><code>MethodDef</code></td><td><code>parseFunctionDecl()</code></td></tr></tbody></table>
|
|
<p><code>main()</code> 有专门校验:参数必须形如 <code>(int $argc, array $argv)</code> 且返回 <code>void</code>(仅 <code>bin</code> 模式强制要求)。</p>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Preprocessor.php#L489-L589">src/Preprocessor.php</a> · <a href="file:///D:\git\php\aot-compiler\src\Preprocessor.php#L685">src/Preprocessor.php</a> · <a href="file:///D:\git\php\aot-compiler\src\Preprocessor.php#L1124">src/Preprocessor.php</a></p>
|
|
<h2>符号仓库</h2>
|
|
<p>收集到的符号统一存放在 <code>Symbol\SymbolRepository</code>(<code>$this->symbols</code>),按 functions / classes / interfaces 分别索引。<code>genExtension()</code>、各类 <code>genXxx</code> 方法都从仓库读取,保证「声明一次、多处生成」。</p>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Symbol\SymbolRepository.php">src/Symbol/SymbolRepository.php</a> · <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L863-L880">src/Translator.php</a></p>
|
|
<h2>属性默认值计划</h2>
|
|
<p>标量/数组属性默认值会被预处理成 <code>ArrayInitPlan</code>,避免 C++ 初始化时重复求值;数组常量也会被标记 special 处理(见 <a href="pages/generator.html">generator</a> 的属性初始化)。</p>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Preprocessor.php#L974-L1002">src/Preprocessor.php</a></p>
|
|
<h2>数值与常量</h2>
|
|
<p><code>loadInternalConstants()</code> 把 PHP 内置常量(排除用户态、<code>TypePHP</code> 扩展组)载入编译期常量表,供常量折叠使用。</p>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L139-L159">src/Translator.php</a></p>
|
|
<h2>相关阅读</h2>
|
|
<ul><li>解析器如何产出 AST → <a href="pages/parser.html">解析器与 AST</a></li><li>遍历中如何改写节点 → <a href="pages/transform.html">AST 转换</a></li><li>符号如何变成 C++ → <a href="pages/generator.html">代码生成</a></li></ul></div></body></html> |