本文档涵盖了 Caddyfile 配置语言的词法分析、解析和处理组件。它详细介绍了原始 Caddyfile 文本如何转换为 Caddy 可用于配置的结构化数据。有关 Caddyfile 指令和语法的更多信息,请参阅 指令。有关将 Caddyfile 转换为 JSON 的适配器系统,请参阅 适配器系统。
Caddyfile 解析系统作为一个多阶段的管道运行,将原始配置文本转换为结构化的 ServerBlock 对象。该过程处理环境变量替换、标记化、导入解析、片段扩展和语法验证。
Caddyfile 解析过程遵循一个定义明确的管道,包含不同的阶段。
来源: caddyconfig/caddyfile/parse.go39-58 caddyconfig/caddyfile/lexer.go56-74
主入口点 Parse() 函数通过首先扩展环境变量,然后对输入进行标记化,最后将标记解析为结构化的服务器块来协调整个过程。
词法分析器将原始文本转换为一系列 Token 对象,这些对象代表离散的语法元素。
来源: caddyconfig/caddyfile/lexer.go40-49 caddyconfig/caddyfile/lexer.go107-295
词法分析器处理几种不同的标记类型,具有不同的处理规则。
| 标记类型 | 分隔符 | 转义 | 行跨接 |
|---|---|---|---|
| 未引用 | 空白字符 | \ 受限 | 否 |
| 双引号 | " | \" 仅 | 是 |
| 反引号引用 | ` | 无 | 是 |
| Heredoc | <<MARKER | 无 | 是 |
| 注释 | # 到 EOL | 不适用 | 否 |
来源: caddyconfig/caddyfile/lexer.go213-294
分词器维护行号跟踪,并处理字节顺序标记、转义的换行符和各种引用机制等特殊情况。
解析器使用 parser 结构在令牌流上运行,该结构维护解析状态并处理复杂的语言特性。
来源: caddyconfig/caddyfile/parse.go113-120 caddyconfig/caddyfile/parse.go766-771
每个 ServerBlock 代表一个独立的配置作用域,具有关联的键(通常是站点地址)和段(指令组)。
{} 界定符。&( 开头的命名路由块。来源: caddyconfig/caddyfile/parse.go766-771
导入系统允许 Caddyfile 配置包含来自外部文件或片段的内容,支持简单的文件包含和参数化导入。
来源: caddyconfig/caddyfile/parse.go356-590 caddyconfig/caddyfile/importargs.go31-94 caddyconfig/caddyfile/parse.go494-582
导入系统支持参数化导入和参数替换。
{args[0]},{args[1]} 用于访问单个参数。{args[0:]},{args[1:3]} 用于参数范围。{block} 和 {blocks.key} 用于包含块内容。{args[0]:default} 语法用于备用值。来源: caddyconfig/caddyfile/importargs.go31-94 caddyconfig/caddyfile/parse.go494-582
Dispenser 在指令处理期间提供了一个结构化的接口来消费令牌。
来源: caddyconfig/caddyfile/dispenser.go29-37 caddyconfig/caddyfile/dispenser.go57-519
Dispenser 维护光标位置和嵌套级别,允许指令处理程序系统地浏览令牌序列,同时提供丰富的错误报告(包含文件和行信息)。
在标记化之前,解析器使用 {$VARIABLE} 语法扩展环境变量。
来源: caddyconfig/caddyfile/parse.go67-111
环境变量替换发生在标记化之前,以确保扩展后的值被正确地解析为令牌流的一部分。变量可以使用冒号语法包含默认值:{$VAR:default_value}。
解析系统提供全面的错误报告,包含位置信息。
来源: caddyconfig/caddyfile/dispenser.go396-432
所有解析错误都包含源文件名、行号以及适用的导入链,从而可以轻松地在即使是复杂的多文件设置中定位和修复配置问题。