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="..."> 不是同一套表面语法。
相关
- Tokenizer - 词法分析
- Token - token 类型与正则
- AlignmentException - 语法异常
- Location - 行列定位