minify-html/gen/dfa.ts

78 lines
1.9 KiB
TypeScript

import yaml from "yaml";
import { DATA_DIR, RUST_OUT_DIR } from "./_common";
import { readFileSync, writeFileSync } from "fs";
import { join } from "path";
import { EOL } from "os";
import { parsePattern, TrieBuilder } from "./trie";
const dfa: { [node: string]: { [transition: string]: string } } = yaml.parse(
readFileSync(join(DATA_DIR, "dfa.yaml"), "utf8")
);
// These states must always exist; see lex/mod.rs for more details.
dfa["TextEntity"] = {};
dfa["AttrValueEntity"] = {};
dfa["Unknown"] = {};
dfa["EOF"] = {};
const nodes = Object.keys(dfa).sort();
const rsTransition = (val: string) => {
const [_, flag, next] = /^([_<+?]?)(.*)$/.exec(val)!;
const consumeMode = {
_: "AccumulateLowerCase",
"": "Accumulate",
"<": "Current",
"+": "Next",
"?": "Reconsume",
}[flag];
return `Transition {
to: State::${next},
consume: ConsumeMode::${consumeMode},
}`;
};
const output = `
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum State {
${nodes.map((n, i) => `${n} = ${i}`).join(`,${EOL} `)}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ConsumeMode {
Current,
Next,
Reconsume,
Accumulate,
AccumulateLowerCase,
}
#[derive(Clone, Copy)]
pub struct Transition {
// Make pub to allow destructuring.
pub to: State,
pub consume: ConsumeMode,
}
${nodes
.map((n) => {
const trieBuilder = new TrieBuilder(n.toUpperCase(), "Transition");
for (const [pat, val] of Object.entries(dfa[n])) {
if (pat == "") {
continue;
}
trieBuilder.addPattern(parsePattern(pat), rsTransition(val));
}
if (dfa[n][""] !== undefined) {
trieBuilder.fillRemaining(rsTransition(dfa[n][""]));
}
return trieBuilder.generate();
})
.join(EOL + EOL)}
pub static TRANSITIONS: [&'static crate::pattern::TrieNode<Transition>; ${
nodes.length
}] = [${nodes.map((n) => n.toUpperCase()).join(", ")}];
`;
writeFileSync(join(RUST_OUT_DIR, "dfa.rs"), output);