Slang 编译器流水线解析(一):词法分析与预处理阶段
Slang 编译器流水线解析一词法分析与预处理阶段【免费下载链接】slangMaking it easier to work with shaders项目地址: https://gitcode.com/GitHub_Trending/sl/slang本篇指南围绕 Slang 着色器语言编译器前端的第一阶段展开如何把一个原始源码缓冲区转换为可供解析器直接消费的扁平Token数组并完整覆盖词法器Lexer与预处理器Preprocessor的数据模型、源码位置编码、宏展开机制、#include解析以及各类失败模式。读者读完将掌握修改 Token 分类、源码位置编码、字面量取值或预处理指令如新增#pragma子指令时的全部关键落点与底层实现原理。本文是docs/generated/design/pipeline/编译流水线系列的第一篇对应的生成规范见 pipeline-01-lex-preprocess.md系列总览见 pipeline/overview.md。阶段输入与输出本阶段的核心契约非常简洁输入一个源码缓冲区通常由 include 系统从磁盘加载外加当前生效的Linkage配置预定义宏、include 搜索路径等。输出一个完全展开的TokenList类型定义见 slang-lexer.h即一段Token序列其中所有的#include、宏展开与条件编译指令均已解析完毕。原始文件字节并不直接交给词法器。SourceFile::decodeContentBlobslang-source-loc.h、slang-source-loc.cpp负责把字节转换为源码文本它会去掉开头的 Unicode BOM并把非 UTF-8 编码解码到一个新缓冲区对于无 BOM 的 UTF-8 文件则原样透传。SourceFile::setContents也走同一个辅助函数因此词法器看到的永远是干净的、无 BOM 的 UTF-8 文本。一个决定整个架构的关键事实是预处理器不会把 token 流式地喂给解析器。第一阶段完整跑完后才产出扁平的 token 列表第二阶段解析才开始。这种解耦正是解析器能够随意使用任意长度 lookahead前视的前提也是后续 02-parse-ast.md 描述解析流程的基础。Lexer词法器词法器实现位于 source/compiler-core/ 目录下由以下文件构成slang-lexer.h / slang-lexer.cpp —Lexer结构体及其initialize/ 词法驱动函数。slang-token.h / slang-token.cpp —Token、TokenType、TokenFlags、TokenList、TokenSpan与TokenReader等数据类型。slang-token-defs.h — 以 X-macro 形式列出全部TokenType值。Token 数据模型每一个 token 携带四类信息slang-token.hTokenType占用一个字节的枚举通过 slang-token-defs.h 的 X-macro#define TOKEN(NAME, DESC) NAME,声明。因为只有一个字节Token可以被紧凑地放入数组。原始文本charsCount加上一个联合体CharsNameUnion联合体要么指向原始字符const char* chars要么指向一个被驻留intern的Name*。TokenFlag::Name位决定联合体当前解释为哪一种getContent()按标志位返回对应的文本切片。SourceLoc单个 32 位整数由 slang-source-loc.h 解码。TokenFlags一个小字节包含AtStartOfLine1 0、AfterWhitespace1 1、ScrubbingNeeded1 2与Name1 3四个标志位。TokenReader同样定义在 slang-token.h为解析器提供了在 token 数组上前进、peek、回退游标的能力——它的ParsingCursor可以保存/恢复位置这是解析器任意前视的基础设施。完整的 token 种类目录与分类见 tokens.md本文不重复罗列。源码位置编码源码位置被压缩成单个uint32_t。SourceManagerslang-source-loc.h、slang-source-loc.cpp在需要时把整数解码回 文件/行/列。这种编码的取舍很明显每个 token 只携带一个廉价字段而不是三个。此外SourceLoc的拷贝构造被显式写成 default而不是手写版本从而保证该类型保持平凡可拷贝trivially copyable以便嵌入到某些联合体中的聚合类型里。Lexer 标志与特殊规则LexerFlags声明于 slang-lexer.h目前只包含一个成员kLexerFlag_SuppressDiagnostics 1 2用于在不报告非法或不受支持字符的情况下进行词法分析——典型场景是在非活动的#if分支内部做 token 化。该标志通过Lexer::getDiagnosticSink生效标志置位时该访问器返回nullptr而不是真实的 sink于是所有经由该访问器上报的扫描期诊断都被静默。唯一的例外是 malformed-UTF-8 诊断它绕过访问器、直接通过lexer-m_sink上报因此在非活动分支内部依然会触发。词法器处理若干 C 语言风格的规则反斜杠行继续\换行会被拼接但最终 token 的源码位置仍映射回原始的物理行。标识符与关键字不做区分所有关键字 token 到达解析器时都是TokenType::Identifier见 slang-token-defs.h 的 X-macro 列表关键字身份由解析器通过名称查找来判定这一设计在 02-parse-ast.md 中有进一步说明。数值/字符串/字符字面量的原文保持原样存放在 token 的原始文本中。词法器只扫描字面量的边界不解码其值取值被推迟到独立的辅助函数见下文。UTF-8 与非 ASCII 输入非 ASCII 输入由 slang-lexer.cpp 中字节级的_advance辅助函数按 UTF-8 解码一个合法的多字节序列被折叠为单个码点交给标识符规则接受。畸形序列会触发invalidUtf8ByteSequence诊断出错的字节以十六进制格式化显示随后被替换为一个空格——这样坏字节只会终止当前 token而不会让整个扫描脱轨。_advance在遇到第一个非法的续接字节时停止而非消费它从而保证恢复点总是落在下一个字符的起始位置。字面量扫描与值提取词法器把字面量的扫描记录其边界为 token 原始文本与解码计算其值分离而且这条分界几乎是干净的扫描只做找到字面量结束位置所需的最小工作外加少量纯语法检查invalidDigitForBase、octalLiteral、quoteCannotBeDelimiter关于字面量含义的一切都被推迟。这三个检查中只有octalLiteral是警告扫描会继续进入_lexNumber(lexer, 8)slang-lexer.cpp 第 2097 行所以017仍会产生一个可用的八进制字面量 token而invalidDigitForBase第 551 行与quoteCannotBeDelimiter第 1797 行都是错误。扫描发生在词法驱动中_lexStringLiteralBody(lexer, char quote)slang-lexer.cpp 第 1731 行同时处理...与...——结束引号字符是参数因此不存在独立的字符字面量模式。它唯一的转义处理是跳过\、\、\\使被转义的引号不会误终止 token它不尝试识别八进制、十六进制或 Unicode 转义形式。相应地它只会报告两种导致找不到结束符的诊断endOfFileInLiteral与newlineInLiteral。原始字符串字面量由_lexRawStringLiteralBody第 1782 行单独扫描它寻找匹配的)delimiter且完全不做转义处理。值解码是按需进行的由 slang-lexer.h 声明的辅助例程完成getIntegerLiteralValue— 解析整数字面量可选地返回后缀、十进制基数标志与溢出标志。getFloatingPointLiteralValue— 解析浮点值。这个辅助函数还会分类后缀把 token 拆成数值部分与后缀部分将后缀映射到FloatingPointLiteralTypeh/hf/fh为Half空后缀或f为Floatl/lf/fl为Double大小写皆可并把解析出的值舍入到该类型对应的精度与范围。同一个枚举还报告两种畸形情况BadSignificand与BadSuffixoutErrorContent携带出错的文本。四个输出参数——outLiteralType、outIsOutOfRange、outPrecisionLost、outErrorContent——都是不可省略的引用。outIsOutOfRange表示结果是0下溢或INFINITY超过字面量类型的最大值而非double的最大值outPrecisionLost仅对十六进制浮点且在值未越界时报告。getStringLiteralTokenValue(token, sink)— 把转义解码为结果字节getFileNameTokenValue是用于#include风格文件名的变体它不处理转义。getCharLiteralValue(token, sink)— 返回 32 位码点失败时返回-1同时也会诊断。该辅助函数掌握单字符规则对短到装不下一个字符的实体发出illegalCharacterLiteral当解码后仍有未消费输入时再次发出该诊断——这就是多字符实体被捕获的方式slang-lexer.cpp 第 1660–1725 行。一个值得注意的细节空后缀被分类为Float而非Double因此仅凭后缀就能决定字面量是否可表示double a 1e300lf; // Double保持有限 float b 1e300; // Float超出范围解码为 INFINITY1e300在double内是合法的但远高于float的最大值所以仅后缀的不同就改变了解码结果slang-lexer.cpp 第 1273–1284 行以及第 1331 行的float解析。字符串/字符辅助函数接受DiagnosticSink*因为所有字面量取值错误都在解码时上报越界的码元与码点、畸形的转义语法、字符计数规则等。转义处理集中在_decodeStringEscapeslang-lexer.cpp 第 1440 行它接收 sink 与 token 的SourceLoc并自行诊断自己的失败未知转义字母、缺少数字或未闭合的\x{...}/\u{...}形式、溢出值会报告invalidStringEscape\u不是恰好 4 位十六进制数字或\U不是恰好 8 位时报告invalidUnicodeStringEscape失败时返回-1。其文法遵循 expressions-literal.md八进制\NNN、十六进制\xNN任意位数、Unicode 转义\uNNNN4 位十六进制、\UNNNNNNNN8 位十六进制与\u{...}花括号形式最多 32 位。在字符串字面量中\xNN映射为单个字节而 Unicode 码点转义通过encodeUnicodePointToUTF8编码为 UTF-8 字节序列。getStringLiteralTokenValue对裸的非转义字节原样拷贝、不再检查 UTF-8 良构性因为词法器的_advance在扫描字面量主体时已经诊断过畸形序列而字符字面量中的主体字节会用getUnicodePointFromUTF8二次重新解码畸形 UTF-8 会被再次拒绝因此在字符字面量里\x与\u没有实际差别。对应的诊断invalidUtf8ByteSequence、invalidStringEscape、invalidUnicodeStringEscape、outOfRangeCodeUnit、outOfRangeCodePointForUtf8都定义在 slang-lexer-diagnostic-defs.h。词法器明确不做的事不分类关键字推迟给名称查找。扫描时不计算数值字面量取值是独立、按需的步骤见上文。默认不跳过空白与注释lexToken会把它们作为独立 token 类型发出过滤由lexAllSemanticTokens以及预处理器的ReadAllTokens完成因此解析器永远看不到它们。Preprocessor预处理器预处理器实现在 slang-preprocessor.cpp公共接口在 slang-preprocessor.h。Preprocessor通过PreprocessorDesc配置包含一个DiagnosticSink*用于消息一个NamePool*用于驻留标识符文本一个ISlangFileSystemExt*与SourceManager*用于 I/O一个可选的IncludeSystem*用于#include解析slang-include-system.h一个可选的DictionaryString, String存放预定义宏一个可选的PreprocessorHandler*——一个回调用于翻译单元结束与文件依赖等事件构建系统用它记录 include 依赖一个可选的PreprocessorContentAssistInfo*供语言服务器在预处理期间收集代码辅助信息。输入流栈模型预处理器维护一个输入流栈原始源文件在栈底被#include的文件与宏展开压在其上。token 向上流动时经过指令识别。每个#include进来的文件都拥有自己的InputFile、自己的词法器、以及自己的一摞Conditional状态因此条件跳过与指令诊断都是按文件隔离的不会干扰父文件。宏展开宏定义存储的是已经词法化好的 token 序列预先被切分成MacroDefinition::Op条目展开就是对这些 op 的回放。参数引用被编译为携带参数索引的参数 opExpandedParam、UnexpandedParam或StringizedParam。调用时MacroInvocation按索引回放对应实参的 token 区间_getArgTokensslang-preprocessor.cpp在ExpandedParam情形下把它包装进ExpansionInputStream使实参 token 自身也参与宏展开——这里不存在按调用创建的伪宏环境。关键行为参数个数不匹配实参数量与形参列表不一致的调用会报告WrongNumberOfArgumentsToMacro并整体跳过不贡献任何 token第 1870 与 1892 行。变参宏只要求非变参部分尾部实参数量任意。自抑制而非深度限制每个在途调用都在一张 busy 列表上_maybeBeginMacroInvocation在MacroInvocation::isBusy发现自己时会让该标识符保持未展开状态第 1462 与 1728 行。因此宏在自己体内引用自己时到达解析器的只是一个普通标识符——既不会再次展开也不会被诊断同一张列表也切断了嵌套展开之间的相互递归。非活动#if分支仍然流经词法器保证行/列计数正确但其内容不做展开只有可能切换活动/非活动状态的指令#if、#ifdef、#ifndef、#else、#elif、#endif才会在非活动块内部被真正求值。预处理指令指令按名称在预处理器状态上的一张回调表中查找因此新增一条指令#pragma、自定义扩展就是在 slang-preprocessor.cpp 中注册一个新的回调。kDirectives表持有 C / HLSL 风格指令集#if及其家族、#include、#define、#undef、#warning、#error、#line、#pragma外加 Slang 的语言选择指令#language/#lang以及 GLSL 指令#version/#extension。每条指令都独占自己的一行因此没有任何指令向输出列表贡献 token。四个非 C 条目中#language/#langHandleLanguageDirective第 4536 行接受一个可选的slang名称后跟版本号#lang [slang] version #language [slang] version它设置源码语言与版本并通过preprocessSource的outDetectedLanguage/outLanguageVersion返回slang-preprocessor.h。版本操作数按名称而非按算术解析无论它是作为标识符还是整数字面量到达其文本都会被交给TypeTextUtil::findLanguageVersion在一张表中查找——表中每个版本携带多个可接受的拼写legacy/default/2018、2025/202a、2026/202b/latest、202c/next。因此#lang 2026、#lang 202b与#lang latest是同一个指令而一个本编译器不认识的版本只是不存在于表中而不是超出范围的数字。注意只有slang被接受为可选语言名该指令已不再识别glsl。不可用操作数产生哪种诊断取决于解析器还能从它身上推断出什么因此共有三种操作数诊断既不是标识符也不是整数字面量ExpectedIntegralVersionNumber无法识别的标识符且未给出slang名称UnknownLanguage—— 语言未指定时孤立的标识符被解读为试图命名一种语言无法识别的整数字面量或显式slang之后的无法识别标识符UnknownLanguageVersion—— 语言已确定该 token 只可能是版本#version第 4501 行接受一个整数当它命名了合法的 GLSL 版本时把检测到的语言切换为 GLSL#extension第 4496 行被接受后直接丢弃。#pragma通过kPragmaDirectives第 4445 行按第二个名称分发目前只有两个条目once与warning。#pragma once把所在文件的唯一标识记录进pragmaOnceUniqueIdentities第 4272 行后续解析到同一标识的#include会在HandleIncludeDirective中提前返回第 3680 行。无法识别的子指令不是错误findPragmaDirective回退到handleUnknownPragmaDirective第 4242 行以UnknownPragmaDirectiveIgnored警告并跳过该行——这与未知的#-指令不同后者由HandleInvalidDirective第 4614 行报告为错误。#if/#elif条件走一个递归下降求值器其值类型是普通的带符号intPreprocessorExpressionValue第 2984 行没有无符号或 64 位模式任何非零结果即选中该分支。命名了非对象宏的标识符在UndefinedIdentifierInPreprocessorExpression警告第 3117 行之后求值为0。EvaluateInfixOp第 3194 行直接套用 C 运算符只有/与%会检查操作数除数为零时诊断并得到0因此、-、*、的溢出既不会被检测也不会被诊断。#include解析#include字符串由IncludeSystemslang-include-system.cpp解析它查询Linkage的搜索路径。对于尖括号形式HandleIncludeDirectiveslang-preprocessor.cpp把OpLess与OpGreater之间的原始 token 拼接为路径字符串并选择IncludeSystem::Mode::System引号形式则从单个StringLiteraltoken 取路径。解析返回一个SourceFile预处理器随后为它压入一个新的输入流。处理程序还会收到handleFileDependency回调以便前端为构建系统建立依赖记录。#pragma warning状态跨文件保持#pragma warning(push/pop/disable/...)的状态由一个WarningStateTrackerslang-preprocessor.cpp跟踪它为每个诊断 id 记录一条以绝对源码位置轴为键的时间线。因为每个#include进来的文件都在各自独立的preprocessSource调用中以全新的Preprocessor处理跟踪器携带了一个persistedAbsoluteSourceLocCounterpreprocessSource在入口用持久化的值播种自己的absoluteSourceLocCounter在出口把推进后的值交还回去——这样时间线的绝对轴在跨文件间保持全局单调而不是每次处理都从 0 重启导致碰撞。一个SLANG_RELEASE_ASSERT会检查交还的计数器保持单调例如防止超大翻译单元导致uint32_t回绕因为一旦违反发布构建中的#pragma warning状态就会被静默错误解析。源码位置保留宏展开产出的 token 分为三类各自采用不同的源码位置策略原始宏体 token—— 从宏定义逐字拷贝的 token。它们的SourceLoc是对应 token 在宏定义中的位置由MacroInvocation::readTokenslang-preprocessor.cpp回放。调用不会创建新的SourceView因此这类诊断指向宏体内部而非调用点。实参 token—— 取自调用点实参列表的 token。_getArgTokens通过PretokenizedInputStream回放记录的 token 区间不做任何改写第 2351 与 2494 行因此每个实参 token 都保留它在调用处被物理词法分析时的SourceLoc。参数被多次使用时每次都回放相同的位置给定#define TWICE(x) ((x) (x))对TWICE(undeclared)中实参的诊断指向调用处的undeclared而不是宏体中的任一(x)——后者按类别 1 的规则才会落点。构造 token—— 全新合成的 token有三种不同的源码位置规则slang-preprocessor.cpp内建宏__LINE__、__FILE__由_pushStreamForSourceLocBuiltin压入赋予合成 tokenm_macroInvocationLoc归因于调用点但报告的行/文件值取自发起的最顶层位置。字符串化参数#x取宏定义中#token 的位置m_macro-tokens.m_tokens[tokenIndex].loc。拼接 tokenx##y从全新的PathInfo::makeTokenPaste()源码视图重新词法分析其来源是##token 的位置tokenPasteLoc。这种三分正是让诊断详见 diagnostics.md在宏自身出错时指向宏体内部、而实参 token 仍指向调用点的机制。只有拼接 token 情形会构建发起位置链格式化诊断时DiagnosticSink会沿着getInitiatingSourceLoc一直走只要视图的PathInfo::Type是TokenPaste就为每一跳发出seeTokenPasteLocation提示。失败模式词法/预处理错误全部通过DiagnosticSink传播可归纳为以下几个层面两阶段诊断划分。非法字符与畸形的数值/字符串/字符字面量诊断分散在两个阶段扫描期错误经过传入词法器initialize的 sink覆盖扫描器无需解释字面量即可看到的问题非法字符、畸形 UTF-8 序列、字面量内遇到文件结束或换行、对该进制非法的数字、遗留八进制字面量、以及把引号用作原始字符串分隔符。解码期错误由传给取值辅助函数的 sink 上报getStringLiteralTokenValue与getCharLiteralValue报告畸形转义语法、越界码元与码点、字符字面量的空或多字符实体getIntegerLiteralValue报告integerLiteralTooLargeForAnyType。getFloatingPointLiteralValue完全不带 sink——它以FloatingPointLiteralType的BadSignificand/BadSuffix外加出错文本返回错误由调用方选择诊断。错误数量上限。两个阶段都汇入 slang-lexer.cpp 中文件局部的diagnose辅助函数它丢弃空 sink并且一旦 sink 的错误计数超过kMaxLexErrorCount100就停止转发——病态损坏的文件不会淹没 sink。抑制诊断时的行为。设置kLexerFlag_SuppressDiagnostics后词法器对畸形输入仍然发出TokenType::Invalidtoken只是不报告诊断——用于被跳过的预处理块内部这些 token 随后会被非活动分支过滤器丢弃。由于抑制是通过Lexer::getDiagnosticSink返回空 sink 实现的它只覆盖使用该访问器的扫描期位置malformed-UTF-8 情形绕过它如果调用方之后向取值辅助函数请求字面量值则会传入自己的 sink仍能看到解码期诊断。预处理错误继续推进。不平衡的#if、未知指令、缺失的 include、循环 include、没有打开条件就出现的#else/#elif/#endif等同样经 sink 上报且预处理器继续运行畸形的指令被跳到行尾、失败的#include从自己的处理函数返回、坏宏调用可以展开为零 token、未闭合的条件在文件结束时对每个仍打开的条件各诊断一次EndOfFileInPreprocessorConditionalslang-preprocessor.cpp 第 4773 行。游离的闭合指令是独立的诊断DirectiveWithoutIf第 3530 行CyclicInclude在解析出的 include 已经在 include 栈上打开时触发第 3710 行该#include被跳过。输出中唯一的EndOfFiletoken 由ReadAllTokens在整个输入栈弹空之后才追加。诊断系统的整体细节见 cross-cutting/diagnostics.md本阶段之后的下游流程见 pipeline/02-parse-ast.md。【免费下载链接】slangMaking it easier to work with shaders项目地址: https://gitcode.com/GitHub_Trending/sl/slang创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Vue History模式刷新404怎么办?Nginx等服务器配置详解与修复指南

Vue History模式刷新404怎么办?Nginx等服务器配置详解与修复指南

简介:一份面向 Vue 项目部署与运维人员的 PDF 技术笔记,专门解决 Vue Router 开启 History 模式后发布到 Nginx,刷新非根路径返回 404 的经典问题。内容从项目打包后的 index.html 入手,逐步排查资源引用路径,并给出两…

2026/9/20 18:30:57 阅读更多 →
RIOT 板卡支持解析:Microchip SAM R34 Xplained Pro(SAMR34J18 LoRa SiP)评估板

RIOT 板卡支持解析:Microchip SAM R34 Xplained Pro(SAMR34J18 LoRa SiP)评估板

RIOT 板卡支持解析:Microchip SAM R34 Xplained Pro(SAMR34J18 LoRa SiP)评估板 【免费下载链接】RIOT RIOT - The friendly OS for IoT 项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT 本篇技术指南以 RIOT 仓库中 samr34…

2026/9/19 21:03:39 阅读更多 →
/grill-me 执行失败?TaoToken 这样改 Cursor 模型通道

/grill-me 执行失败?TaoToken 这样改 Cursor 模型通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/20 22:38:43 阅读更多 →

最新新闻

Nix 2.27.0 特性详解:Git 子模块自声明、LFS 拉取、BLAKE3 哈希与 chroot store 增强

Nix 2.27.0 特性详解:Git 子模块自声明、LFS 拉取、BLAKE3 哈希与 chroot store 增强

Nix 2.27.0 特性详解:Git 子模块自声明、LFS 拉取、BLAKE3 哈希与 chroot store 增强 【免费下载链接】nix Nix, the purely functional package manager 项目地址: https://gitcode.com/gh_mirrors/ni/nix Nix 2.27.0(2025-03-03 发布&#xff0…

2026/9/21 2:39:28 阅读更多 →
url_launcher_ios 深度解析:Flutter iOS 端 URL 启动插件的实现原理与实战配置

url_launcher_ios 深度解析:Flutter iOS 端 URL 启动插件的实现原理与实战配置

url_launcher_ios 深度解析:Flutter iOS 端 URL 启动插件的实现原理与实战配置 【免费下载链接】plugins Plugins for Flutter maintained by the Flutter team 项目地址: https://gitcode.com/gh_mirrors/pl/plugins 导读 url_launcher_ios 是 Flutter 官方…

2026/9/21 2:39:28 阅读更多 →
Readest OPDS 兼容性修复实录:HTTPS 源发布绝对 http:// 自链接导致子 Feed 404 的根因与 resolveURL 升级方案

Readest OPDS 兼容性修复实录:HTTPS 源发布绝对 http:// 自链接导致子 Feed 404 的根因与 resolveURL 升级方案

桌面应用跨平台前端 【免费下载链接】readest Readest is a modern, feature-rich ebook reader designed for avid readers offering seamless cross-platform access, powerful tools, and an intuitive interface to elevate your reading experience. 项目地址:…

2026/9/21 2:39:28 阅读更多 →
数据安全治理解决方案PPT全解析:框架搭建、实战落地与常见问题

数据安全治理解决方案PPT全解析:框架搭建、实战落地与常见问题

简介:这份PPT资源是一套完整的数据安全治理解决方案,面向企业信息安全负责人、数据治理工程师及IT管理者,可用于内部培训、项目方案编制或售前交流。全篇围绕“背景及挑战—解决方案—未来展望”三层展开:先分析合规监管要求、数据…

2026/9/21 2:39:28 阅读更多 →
Flet 发布准备全流程指南:版本号、变更日志与弃用审计

Flet 发布准备全流程指南:版本号、变更日志与弃用审计

Flet 发布准备全流程指南:版本号、变更日志与弃用审计 【免费下载链接】flet Build realtime web, mobile and desktop apps in Python only. No frontend experience required. 项目地址: https://gitcode.com/gh_mirrors/fl/flet 本文基于 Flet 仓库中维护…

2026/9/21 2:39:28 阅读更多 →
CFD-POST完整加载Fluent瞬态结果:Autosave配置与实操指南

CFD-POST完整加载Fluent瞬态结果:Autosave配置与实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 2:38:28 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →