tdmul
Version:
Transfer Data Mark-Up Language - Read, write, and manipulate TDMUL files
97 lines (78 loc) • 2.68 kB
JavaScript
class Parser {
constructor(tokens) {
this.tokens = tokens;
this.index = 0;
this.references = {};
}
parse() {
const result = {};
while (this.index < this.tokens.length) {
const token = this.tokens[this.index];
if (!token.value) {
this.index++;
continue;
}
if (token.value.endsWith("::")) {
const sectionName = token.value.slice(0, -2).trim();
this.index++;
result[sectionName] = this.parseSection(token.indent + 4);
} else {
this.index++;
}
}
return result;
}
parseSection(baseIndent) {
const items = [];
while (this.index < this.tokens.length) {
const token = this.tokens[this.index];
if (token.indent < baseIndent) break;
if (!token.value) { this.index++; continue; }
if (token.value.endsWith(":")) {
const key = token.value.slice(0, -1).trim();
this.index++;
const item = this.parseItem(baseIndent + 4);
items.push({ [key]: item });
} else {
this.index++;
}
}
return items;
}
parseItem(baseIndent) {
const obj = {};
while (this.index < this.tokens.length) {
const token = this.tokens[this.index];
if (token.indent < baseIndent) break;
if (!token.value) { this.index++; continue; }
const line = token.value.trim();
if (line.includes("=")) {
let [key, value] = line.split("=");
key = key.trim();
value = value.trim();
if (value.startsWith("&")) {
const refName = value.slice(1);
value = this.references[refName] ?? null;
} else {
value = this.autoCast(value);
}
obj[key] = value;
if (key.startsWith("&")) this.references[key.slice(1)] = value;
}
this.index++;
}
return obj;
}
autoCast(value) {
if (value.startsWith("[") && value.endsWith("]")) {
const inner = value.slice(1, -1).trim();
if (!inner) return [];
return inner.split(",").map(v => this.autoCast(v.trim()));
}
if (value === "true") return true;
if (value === "false") return false;
if (!isNaN(value)) return Number(value);
return value;
}
}
module.exports = Parser;