diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2019-10-05 16:24:42 -0400 |
---|---|---|
committer | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2019-10-05 18:28:30 -0400 |
commit | 50a47348a7a040d1bcaf0a12a38cca049dc207f7 (patch) | |
tree | de61259ab82a7a681bd7716970e0d2d80aa5c286 /ext/bg/js/deinflector.js | |
parent | 30263c3db84714a01e516c1f56225b423f5c8612 (diff) |
Optimize internal data structure used by the Deinflector class
Diffstat (limited to 'ext/bg/js/deinflector.js')
-rw-r--r-- | ext/bg/js/deinflector.js | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/ext/bg/js/deinflector.js b/ext/bg/js/deinflector.js index ad77895c..ce4b2961 100644 --- a/ext/bg/js/deinflector.js +++ b/ext/bg/js/deinflector.js @@ -19,51 +19,74 @@ class Deinflector { constructor(reasons) { - this.reasons = reasons; + this.reasons = Deinflector.normalizeReasons(reasons); } deinflect(source) { const results = [{ source, term: source, - rules: [], + rules: 0, definitions: [], reasons: [] }]; for (let i = 0; i < results.length; ++i) { - const entry = results[i]; - - for (const reason in this.reasons) { - for (const variant of this.reasons[reason]) { - let accept = entry.rules.length === 0; - if (!accept) { - for (const rule of entry.rules) { - if (variant.rulesIn.includes(rule)) { - accept = true; - break; - } - } - } - - if (!accept || !entry.term.endsWith(variant.kanaIn)) { - continue; - } - - const term = entry.term.slice(0, -variant.kanaIn.length) + variant.kanaOut; - if (term.length === 0) { + const {rules, term, reasons} = results[i]; + for (const [reason, variants] of this.reasons) { + for (const [kanaIn, kanaOut, rulesIn, rulesOut] of variants) { + if ( + (rules !== 0 && (rules & rulesIn) === 0) || + !term.endsWith(kanaIn) || + (term.length - kanaIn.length + kanaOut.length) <= 0 + ) { continue; } results.push({ source, - term, - rules: variant.rulesOut, + term: term.slice(0, -kanaIn.length) + kanaOut, + rules: rulesOut, definitions: [], - reasons: [reason, ...entry.reasons] + reasons: [reason, ...reasons] }); } } } return results; } + + static normalizeReasons(reasons) { + const normalizedReasons = []; + for (const reason in reasons) { + const variants = []; + for (const {kanaIn, kanaOut, rulesIn, rulesOut} of reasons[reason]) { + variants.push([ + kanaIn, + kanaOut, + Deinflector.rulesToRuleFlags(rulesIn), + Deinflector.rulesToRuleFlags(rulesOut) + ]); + } + normalizedReasons.push([reason, variants]); + } + return normalizedReasons; + } + + static rulesToRuleFlags(rules) { + const ruleTypes = Deinflector.ruleTypes; + let value = 0; + for (const rule of rules) { + value |= ruleTypes[rule]; + } + return value; + } } + +Deinflector.ruleTypes = { + 'v1': 0b0000001, // Verb ichidan + 'v5': 0b0000010, // Verb godan + 'vs': 0b0000100, // Verb suru + 'vk': 0b0001000, // Verb kuru + 'adj-i': 0b0010000, // Adjective i + 'iru': 0b0100000, // Intermediate -iru endings for progressive or perfect tense +}; |