TextParser

手写递归下降解析器

基本信息

属性 值
路径 com.github.lunatrius.ingameinfo.parser.text.TextParser
行数 302(parser 包最大文件)
实现 IParser

本 mod 只有这一处完全手写的编译器式组件: Tokenizer 词法 → 本类语法 → Value 树。 XML / JSON 两条路径都交给现成库。

load(:34-56)

public boolean load(InputStream inputStream) { ... }

把流读成字符串,交给 Tokenizer 的 tokenize(String)。 tokenize 声明 throws Exception,本类必须处理。

parse(:58-70)

入口 alignments(format),然后链式下降。

递归下降结构

方法的 Tail 后缀命名表示「同一层级的重复」,是经典的 LL(1) 递归下降范式:

层 方法 行
顶层 alignments :72
alignmentsTail :76
alignment :84
行 lines :108
linesTail :112
line :120
值 values :137
valuesTail :141
value :149
原子 string :168

⚠️ lines / linesTail 的签名是 boolean lines(List<List<Value>> lines) —— 参数不是本层的输出容器,而是「已解析部分的累加器」。 lines 内部先调 linesTail,再按需要调 line 把新行 add 进去。 values / valuesTail 同构。

异常处理

lines / linesTail / line / values / valuesTail / value 六个方法都 throws AlignmentException。

AlignmentException 只带两个信息: 出错的 Alignment 与 isValid() 布尔。

⚠️ alignment(:84)本身不 throws —— 它内部 catch 掉 Alignment.parse 抛的异常并返回 false。 所以对齐名写错返回 false(整个配置加载失败), 而行/值语法错抛 AlignmentException。 两条失败路径的行为不一致。

string(:168)

最底层的原子解析,接收一个 lexem 参数 (表明它按当前 token 的字面量分派,不同字面量走不同构造)。

与 XML/JSON 的能力差异

⚠️ TXT 格式不支持别名: ValueRegistry 的 forName 能解析 31 个主名 + 全部别名, 但文本语法里函数名是裸 token,别名是否可用取决于 value(Value) 方法的字面量匹配表 —— 该方法(:149-166,约 18 行) 需要逐个列出允许的 token。

⚠️ TXT 也不支持 at= 属性语法, 对齐段的写法由 alignment(:84-106)定义,与 XML 的 <lines at="..."> 不是同一套表面语法。

相关