docs: 增加注释 doc
This commit is contained in:
parent
2c4374554e
commit
a75e76e05a
@ -10,61 +10,54 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CloudDSLParser — .cloud 配置文件解析器
|
* CloudDSL 配置文件解析器。
|
||||||
* <p>
|
|
||||||
* 作用:
|
|
||||||
* - 读取 Snow 构建工具自定义的 .cloud 文件
|
|
||||||
* - 将内容转换为内存中的 {@link Project} 模型
|
|
||||||
* <p>
|
|
||||||
* 解析规则(:
|
|
||||||
* <p>
|
|
||||||
* 1. 顶级区块(project、properties、repositories、dependencies、build)
|
|
||||||
* 以 “sectionName {” 开始,以 “}” 结束。
|
|
||||||
* <p>
|
|
||||||
* 2. 区块内部识别 “key = value” 形式的赋值。
|
|
||||||
* <p>
|
|
||||||
* 3. build 区块允许嵌套;内部键通过 “.” 展平,
|
|
||||||
* 例如 compile.enabled = true。
|
|
||||||
* <p>
|
* <p>
|
||||||
|
* 负责将自定义的 .cloud 构建配置文件解析为 {@link Project} 模型。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>顶级区块(如 project、properties、repositories、dependencies、build)以 <code>sectionName {</code> 开始,以 <code>}</code> 结束</li>
|
||||||
|
* <li>区块内部只识别 <code>key = value</code> 赋值,行尾可有 <code># 注释</code></li>
|
||||||
|
* <li>build 区块支持嵌套,内部键通过 <code>.</code> 展平,例如 <code>compile.enabled = true</code></li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 示例 .cloud 文件片段:
|
||||||
|
* project {
|
||||||
|
* group = com.example
|
||||||
|
* artifact = demo
|
||||||
|
* version = 1.0.0
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public final class CloudDSLParser {
|
public final class CloudDSLParser {
|
||||||
|
|
||||||
/* ---------- 正则表达式 ---------- */
|
/** 匹配 sectionName { 的行 */
|
||||||
|
|
||||||
/**
|
|
||||||
* 匹配 “sectionName {” 形式的行
|
|
||||||
*/
|
|
||||||
private static final Pattern SECTION_HEADER = Pattern.compile("^(\\w+)\\s*\\{\\s*$");
|
private static final Pattern SECTION_HEADER = Pattern.compile("^(\\w+)\\s*\\{\\s*$");
|
||||||
|
/** 匹配 key = value 行,忽略行尾注释 */
|
||||||
/**
|
|
||||||
* 匹配 “key = value” 行。
|
|
||||||
* value 允许空格,并忽略行尾 “# …” 注释。
|
|
||||||
*/
|
|
||||||
private static final Pattern KEY_VALUE = Pattern.compile("^(\\w+)\\s*=\\s*([^#]+?)\\s*(?:#.*)?$");
|
private static final Pattern KEY_VALUE = Pattern.compile("^(\\w+)\\s*=\\s*([^#]+?)\\s*(?:#.*)?$");
|
||||||
|
/** 匹配仅为 } 的行 */
|
||||||
/**
|
|
||||||
* 匹配仅包含 “}” 的行(可有前后空白)
|
|
||||||
*/
|
|
||||||
private static final Pattern BLOCK_END = Pattern.compile("^}\\s*$");
|
private static final Pattern BLOCK_END = Pattern.compile("^}\\s*$");
|
||||||
|
|
||||||
/**
|
/** 私有构造方法,工具类禁止实例化 */
|
||||||
* 私有构造,禁止实例化
|
private CloudDSLParser() {}
|
||||||
*/
|
|
||||||
private CloudDSLParser() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析指定 .cloud 文件并生成 {@link Project} 对象。
|
* 解析指定 .cloud 文件为 {@link Project} 对象。
|
||||||
|
* <ul>
|
||||||
|
* <li>遇到语法错误(括号不配对、无法识别的行)时会抛出异常</li>
|
||||||
|
* <li>支持嵌套区块和注释</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param path 文件路径
|
* @param path .cloud 文件路径
|
||||||
* @return 解析后的 Project
|
* @return 解析得到的 Project 实例
|
||||||
* @throws IOException 文件读取失败
|
* @throws IOException 文件读取失败
|
||||||
* @throws IllegalStateException 语法错误(如括号不匹配、未知语句)
|
* @throws IllegalStateException 文件内容格式非法或语法错误
|
||||||
*/
|
*/
|
||||||
public static Project parse(Path path) throws IOException {
|
public static Project parse(Path path) throws IOException {
|
||||||
|
|
||||||
Deque<String> sectionStack = new ArrayDeque<>(); // 记录当前区块层级
|
Deque<String> sectionStack = new ArrayDeque<>(); // 当前区块栈
|
||||||
Map<String, String> flatMap = new LinkedHashMap<>(); // 扁平化 key → value
|
Map<String, String> flatMap = new LinkedHashMap<>(); // 扁平化后的 key → value
|
||||||
|
|
||||||
List<String> lines = Files.readAllLines(path);
|
List<String> lines = Files.readAllLines(path);
|
||||||
|
|
||||||
@ -73,19 +66,19 @@ public final class CloudDSLParser {
|
|||||||
lineNo++;
|
lineNo++;
|
||||||
String line = raw.trim();
|
String line = raw.trim();
|
||||||
|
|
||||||
/* 1. 跳过空行和注释 */
|
// 跳过空行和注释
|
||||||
if (line.isEmpty() || line.startsWith("#")) {
|
if (line.isEmpty() || line.startsWith("#")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2. 区块起始:sectionName { */
|
// 区块起始
|
||||||
Matcher sec = SECTION_HEADER.matcher(line);
|
Matcher sec = SECTION_HEADER.matcher(line);
|
||||||
if (sec.matches()) {
|
if (sec.matches()) {
|
||||||
sectionStack.push(sec.group(1));
|
sectionStack.push(sec.group(1));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3. 区块结束:} */
|
// 区块结束
|
||||||
if (BLOCK_END.matcher(line).matches()) {
|
if (BLOCK_END.matcher(line).matches()) {
|
||||||
if (sectionStack.isEmpty()) {
|
if (sectionStack.isEmpty()) {
|
||||||
throw new IllegalStateException("第 " + lineNo + " 行出现未配对的 '}'");
|
throw new IllegalStateException("第 " + lineNo + " 行出现未配对的 '}'");
|
||||||
@ -94,13 +87,13 @@ public final class CloudDSLParser {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 4. 键值对:key = value */
|
// 键值对
|
||||||
Matcher kv = KEY_VALUE.matcher(line);
|
Matcher kv = KEY_VALUE.matcher(line);
|
||||||
if (kv.matches()) {
|
if (kv.matches()) {
|
||||||
String key = kv.group(1).trim();
|
String key = kv.group(1).trim();
|
||||||
String value = kv.group(2).trim();
|
String value = kv.group(2).trim();
|
||||||
|
|
||||||
/* 4.1 计算前缀(栈倒序,即从外到内) */
|
// 计算区块前缀
|
||||||
String prefix = String.join(".", (Iterable<String>) sectionStack::descendingIterator);
|
String prefix = String.join(".", (Iterable<String>) sectionStack::descendingIterator);
|
||||||
if (!prefix.isEmpty()) {
|
if (!prefix.isEmpty()) {
|
||||||
key = prefix + "." + key;
|
key = prefix + "." + key;
|
||||||
@ -110,16 +103,16 @@ public final class CloudDSLParser {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 5. 无法识别的行 */
|
// 无法识别的行
|
||||||
throw new IllegalStateException("无法解析第 " + lineNo + " 行: " + raw);
|
throw new IllegalStateException("无法解析第 " + lineNo + " 行: " + raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 6. 检查括号是否全部闭合 */
|
// 检查区块是否全部闭合
|
||||||
if (!sectionStack.isEmpty()) {
|
if (!sectionStack.isEmpty()) {
|
||||||
throw new IllegalStateException("文件结束但区块未闭合:" + sectionStack);
|
throw new IllegalStateException("文件结束但区块未闭合:" + sectionStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 7. 构造 Project 模型 */
|
// 构建 Project 模型
|
||||||
return Project.fromFlatMap(flatMap);
|
return Project.fromFlatMap(flatMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user