<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Parser - 标签 - 星河拾贝录</title><link>https://blog.liubang.cc/tags/parser/</link><description>Parser - 标签 - 星河拾贝录</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><managingEditor>it.liubang@gmail.com (liubang)</managingEditor><webMaster>it.liubang@gmail.com (liubang)</webMaster><copyright>Copyright © 2019-2026 LiuBang. All Rights Reserved.</copyright><lastBuildDate>Sat, 23 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.liubang.cc/tags/parser/" rel="self" type="application/rss+xml"/><item><title>从源码到 AST：Flux Parser 的实现</title><link>https://blog.liubang.cc/flux/2026-05-23-flux-engine-02-parser-and-ast/</link><pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate><author><name>liubang</name></author><guid>https://blog.liubang.cc/flux/2026-05-23-flux-engine-02-parser-and-ast/</guid><description><![CDATA[<p>语言实现的第一层是把源码变成结构化数据。对 <code>cpp/pl/flux</code> 来说，这一层由 <code>syntax/scanner.rl</code>、生成的 scanner、<code>syntax/parser.cpp</code> 和 <code>syntax/ast.h</code> 组成。它的目标不是只让正确程序通过，而是尽量为后面的 runtime、CLI、LSP 和测试提供稳定、可定位的 AST。</p>
<h2 id="scanner把字符流切成-token" class="headerLink">
    <a href="#scanner%e6%8a%8a%e5%ad%97%e7%ac%a6%e6%b5%81%e5%88%87%e6%88%90-token" class="header-mark"></a>Scanner：把字符流切成 token</h2><p>Flux 的词法并不只是普通标识符和数字。当前 scanner 覆盖了关键字、字符串、字符串插值、duration、RFC3339 风格 datetime、正则字面量、注释、pipe-forward、比较运算符、属性注解和类型语法相关 token。</p>
<p>正则字面量是一个典型细节。<code>/cpu.*/</code> 和除法操作符都以 <code>/</code> 开头，scanner 不能只靠单个字符判断。当前实现区分表达式上下文，在可能期待表达式的位置接受 regex literal，在普通二元运算位置按除法处理。这类细节决定了 parser 后面看到的 token 是否有语义。</p>
<p>scanner 还维护 line/column 信息。这个成本看起来不大，但收益很高：parser error、AST dump、LSP diagnostics、goto definition、semantic tokens 都需要准确的 source location。</p>
<h2 id="token-设计里几个容易低估的点" class="headerLink">
    <a href="#token-%e8%ae%be%e8%ae%a1%e9%87%8c%e5%87%a0%e4%b8%aa%e5%ae%b9%e6%98%93%e4%bd%8e%e4%bc%b0%e7%9a%84%e7%82%b9" class="header-mark"></a>Token 设计里几个容易低估的点</h2><p>第一个点是 <code>import</code>、<code>option</code>、<code>builtin</code>、<code>testcase</code> 这些关键字不是普通标识符。它们在文件级语法和语句级语法里有特殊入口，如果 scanner 不提前分类，parser 就必须在更多地方做字符串判断。</p>
<p>第二个点是 duration 和 unsigned integer。<code>1h</code>、<code>5m</code>、<code>42u</code> 看起来像数字加后缀，但语义完全不同。duration 后续要参与 time range/window 计算；unsigned integer 则进入普通 numeric value。scanner 和 parser 必须在 AST 层把它们分开。</p>
<p>第三个点是字符串插值。<code>&quot;host ${user}&quot;</code> 不是普通字符串拼接，parser 需要保留插值表达式，这样 runtime 才能在当前 environment 下求值。</p>]]></description></item></channel></rss>