From a75e76e05a022761de8ecda4b27ff53b2acca295 Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 24 Jun 2025 14:04:34 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A=20?= =?UTF-8?q?doc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/jcnc/snow/pkg/dsl/CloudDSLParser.java | 89 +++++++++---------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/src/main/java/org/jcnc/snow/pkg/dsl/CloudDSLParser.java b/src/main/java/org/jcnc/snow/pkg/dsl/CloudDSLParser.java index c707a65..5c61337 100644 --- a/src/main/java/org/jcnc/snow/pkg/dsl/CloudDSLParser.java +++ b/src/main/java/org/jcnc/snow/pkg/dsl/CloudDSLParser.java @@ -10,61 +10,54 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * CloudDSLParser — .cloud 配置文件解析器 - *

- * 作用: - * - 读取 Snow 构建工具自定义的 .cloud 文件 - * - 将内容转换为内存中的 {@link Project} 模型 - *

- * 解析规则(: - *

- * 1. 顶级区块(project、properties、repositories、dependencies、build) - * 以 “sectionName {” 开始,以 “}” 结束。 - *

- * 2. 区块内部识别 “key = value” 形式的赋值。 - *

- * 3. build 区块允许嵌套;内部键通过 “.” 展平, - * 例如 compile.enabled = true。 + * CloudDSL 配置文件解析器。 *

+ * 负责将自定义的 .cloud 构建配置文件解析为 {@link Project} 模型。 + *

+ * + * + * + *
+ * 示例 .cloud 文件片段:
+ * project {
+ *   group = com.example
+ *   artifact = demo
+ *   version = 1.0.0
+ * }
+ * 
*/ public final class CloudDSLParser { - /* ---------- 正则表达式 ---------- */ - - /** - * 匹配 “sectionName {” 形式的行 - */ + /** 匹配 sectionName { 的行 */ private static final Pattern SECTION_HEADER = Pattern.compile("^(\\w+)\\s*\\{\\s*$"); - - /** - * 匹配 “key = value” 行。 - * value 允许空格,并忽略行尾 “# …” 注释。 - */ + /** 匹配 key = value 行,忽略行尾注释 */ private static final Pattern KEY_VALUE = Pattern.compile("^(\\w+)\\s*=\\s*([^#]+?)\\s*(?:#.*)?$"); - - /** - * 匹配仅包含 “}” 的行(可有前后空白) - */ + /** 匹配仅为 } 的行 */ private static final Pattern BLOCK_END = Pattern.compile("^}\\s*$"); - /** - * 私有构造,禁止实例化 - */ - private CloudDSLParser() { - } + /** 私有构造方法,工具类禁止实例化 */ + private CloudDSLParser() {} /** - * 解析指定 .cloud 文件并生成 {@link Project} 对象。 + * 解析指定 .cloud 文件为 {@link Project} 对象。 + * * - * @param path 文件路径 - * @return 解析后的 Project + * @param path .cloud 文件路径 + * @return 解析得到的 Project 实例 * @throws IOException 文件读取失败 - * @throws IllegalStateException 语法错误(如括号不匹配、未知语句) + * @throws IllegalStateException 文件内容格式非法或语法错误 */ public static Project parse(Path path) throws IOException { - Deque sectionStack = new ArrayDeque<>(); // 记录当前区块层级 - Map flatMap = new LinkedHashMap<>(); // 扁平化 key → value + Deque sectionStack = new ArrayDeque<>(); // 当前区块栈 + Map flatMap = new LinkedHashMap<>(); // 扁平化后的 key → value List lines = Files.readAllLines(path); @@ -73,19 +66,19 @@ public final class CloudDSLParser { lineNo++; String line = raw.trim(); - /* 1. 跳过空行和注释 */ + // 跳过空行和注释 if (line.isEmpty() || line.startsWith("#")) { continue; } - /* 2. 区块起始:sectionName { */ + // 区块起始 Matcher sec = SECTION_HEADER.matcher(line); if (sec.matches()) { sectionStack.push(sec.group(1)); continue; } - /* 3. 区块结束:} */ + // 区块结束 if (BLOCK_END.matcher(line).matches()) { if (sectionStack.isEmpty()) { throw new IllegalStateException("第 " + lineNo + " 行出现未配对的 '}'"); @@ -94,13 +87,13 @@ public final class CloudDSLParser { continue; } - /* 4. 键值对:key = value */ + // 键值对 Matcher kv = KEY_VALUE.matcher(line); if (kv.matches()) { String key = kv.group(1).trim(); String value = kv.group(2).trim(); - /* 4.1 计算前缀(栈倒序,即从外到内) */ + // 计算区块前缀 String prefix = String.join(".", (Iterable) sectionStack::descendingIterator); if (!prefix.isEmpty()) { key = prefix + "." + key; @@ -110,16 +103,16 @@ public final class CloudDSLParser { continue; } - /* 5. 无法识别的行 */ + // 无法识别的行 throw new IllegalStateException("无法解析第 " + lineNo + " 行: " + raw); } - /* 6. 检查括号是否全部闭合 */ + // 检查区块是否全部闭合 if (!sectionStack.isEmpty()) { throw new IllegalStateException("文件结束但区块未闭合:" + sectionStack); } - /* 7. 构造 Project 模型 */ + // 构建 Project 模型 return Project.fromFlatMap(flatMap); } }