7 #include "libime/table/tabledecoder.h" 15 #include <string_view> 18 #include <fcitx-utils/utf8.h> 19 #include "libime/core/languagemodel.h" 20 #include "libime/core/lattice.h" 21 #include "libime/core/segmentgraph.h" 22 #include "libime/table/tablebaseddictionary.h" 23 #include "tabledecoder_p.h" 24 #include "tableoptions.h" 25 #include "tablerule.h" 31 bool isNotPlaceHolder(
const TableRuleEntry &entry) {
32 return !entry.isPlaceHolder();
35 bool checkRuleCanBeUsedAsAutoRule(
const TableRule &rule) {
36 if (rule.flag() != TableRuleFlag::LengthEqual) {
40 auto range = rule.entries() | std::views::filter(isNotPlaceHolder);
41 auto iter = std::begin(range);
42 auto end = std::end(range);
47 if (iter->character() == currentChar) {
48 if (iter->flag() == TableRuleEntryFlag::FromFront &&
49 iter->index() == currentIndex) {
62 if (currentIndex == 1) {
67 return currentChar == rule.phraseLength() + 1;
71 uint32_t TableLatticeNode::index()
const {
72 return d_ptr ? d_ptr->index_ : 0xFFFFFFFFU;
75 PhraseFlag TableLatticeNode::flag()
const {
76 return d_ptr ? d_ptr->flag_ : PhraseFlag::None;
79 const std::string &TableLatticeNode::code()
const {
80 static const std::string empty;
87 size_t TableLatticeNode::codeLength()
const {
91 return d_ptr->codeLength_;
94 TableLatticeNode::TableLatticeNode(
95 std::string_view word, WordIndex idx, SegmentGraphPath path,
96 const State &state,
float cost,
97 std::unique_ptr<TableLatticeNodePrivate> data)
98 : LatticeNode(word, idx, std::move(path), state, cost),
99 d_ptr(std::move(data)) {}
101 TableLatticeNode::~TableLatticeNode() =
default;
103 LatticeNode *TableDecoder::createLatticeNodeImpl(
104 const SegmentGraphBase & ,
const LanguageModelBase * ,
105 std::string_view word, WordIndex idx, SegmentGraphPath path,
106 const State &state,
float cost, std::unique_ptr<LatticeNodeData> data,
108 std::unique_ptr<TableLatticeNodePrivate> tableData(
109 static_cast<TableLatticeNodePrivate *>(data.release()));
110 return new TableLatticeNode(word, idx, std::move(path), state, cost,
111 std::move(tableData));
114 bool TableDecoder::needSort(
const SegmentGraph &graph,
115 const SegmentGraphNode * )
const {
116 return graph.start().nextSize() != 1;
119 SegmentGraph graphForCode(std::string_view s,
120 const TableBasedDictionary &dict) {
121 SegmentGraph graph{std::string(s)};
125 graph.addNext(0, graph.size());
126 auto codeLength = fcitx::utf8::length(graph.data());
128 if (dict.hasRule() && !dict.tableOptions().autoRuleSet().empty()) {
129 const auto &ruleSet = dict.tableOptions().autoRuleSet();
130 for (
const auto &ruleName : ruleSet) {
131 const auto *rule = dict.findRule(ruleName);
132 if (!rule || codeLength != rule->codeLength() ||
133 !checkRuleCanBeUsedAsAutoRule(*rule)) {
137 std::vector<int> charSizes(rule->phraseLength());
138 for (
const auto &entry :
139 rule->entries() | std::views::filter(isNotPlaceHolder)) {
140 auto &charSize = charSizes[entry.character() - 1];
141 charSize = std::max(charSize, entry.index());
145 for (
auto charSize : charSizes) {
146 graph.addNext(fcitx::utf8::ncharByteLength(graph.data().begin(),
148 fcitx::utf8::ncharByteLength(
149 graph.data().begin(), lastIndex + charSize));
150 lastIndex += charSize;