t-suw****@users*****
t-suw****@users*****
2007年 9月 9日 (日) 11:59:49 JST
Index: AquaSKK/src/context/SKKRomanKanaConverter.cpp diff -u AquaSKK/src/context/SKKRomanKanaConverter.cpp:1.1.2.1 AquaSKK/src/context/SKKRomanKanaConverter.cpp:1.1.2.2 --- AquaSKK/src/context/SKKRomanKanaConverter.cpp:1.1.2.1 Sat Sep 8 22:35:18 2007 +++ AquaSKK/src/context/SKKRomanKanaConverter.cpp Sun Sep 9 11:59:49 2007 @@ -21,7 +21,6 @@ #include <iostream> #include <fstream> #include <sstream> -#include <map> #include "jconv.h" #include "SKKRomanKanaConverter.h" @@ -48,126 +47,28 @@ } // ====================================================================== -// SKKRomanKanaConverter::Node ã¤ã³ã¿ãã§ã¼ã¹ -// ====================================================================== -class SKKRomanKanaConverter::Node { - std::string hirakana_; - std::string katakana_; - std::string jisx0201kana_; - std::string next_; - - std::map<char, SKKRomanKanaConverter::Node> children_; - -public: - Node() {} - Node(const std::string& hirakana, const std::string& katakana, - const std::string& jisx0201kana, const std::string& next) - : hirakana_(hirakana), katakana_(katakana), jisx0201kana_(jisx0201kana), next_(next) {} - - // åæå - void Clear() { - children_.clear(); - } - - // ãã¼ã追å - void Add(const std::string& str, const Node& node, int depth = 0) { - // æ«ç«¯ãï¼ - if(str.size() - 1 == depth) { - children_[str[depth]] = node; - } else { - children_[str[depth]].Add(str, node, depth + 1); // å帰追å - } - } - - // ãã¼ãæ¤ç´¢ - const Node* Traverse(const std::string& str, int& match_length, int depth = 0) { - // [1] ãã¼ã¿ä¸è¶³(ex. "k" ã "ch" ãªã©) - if(depth == str.size()) { - match_length = 0; - return 0; - } - - // ä¸è´ï¼ - if(children_.find(str[depth]) != children_.end()) { - Node& leaf = children_[str[depth]]; - - // æ«ç«¯ã§ãªããªãå帰æ¤ç´¢ - if(!leaf.children_.empty()) { - return leaf.Traverse(str, match_length, depth + 1); - } - - // [2] å®å ¨ä¸è´ - match_length = depth + 1; - return &leaf; - } - - // [3] é¨åä¸è´(ex. "kb" ã "chm" ãªã©) - if(0 < depth) { - match_length = depth; - - // ç¯ãã¤èã§ããããnãã®ãããªå ´åã«ã¯ãä¸è´ã¨ãã¦æ±ã - if(!hirakana_.empty()) { - return this; - } - - return 0; - } - - // [4] å ¨ãä¸è´ããªãã£ã - match_length = -1; - return 0; - } - - // ãã¼ãæåååå¾ - const std::string& KanaString(SKK::InputMode mode) const { - switch(mode) { - case SKK::Hirakana: - return hirakana_; - - case SKK::Katakana: - return katakana_; - - case SKK::Jisx0201Kana: - return jisx0201kana_; - - default: - std::cerr << "SKKRomanKanaConverter::Node::KanaString(): invalid mode [" << mode << "]" << std::endl; - break; - } - } - - // 次ç¶æ æåååå¾ - const std::string& NextState() const { - return next_; - } -}; - -// ====================================================================== // SKKRomanKanaConverter ã¤ã³ã¿ãã§ã¼ã¹ // ====================================================================== +SKKRomanKanaConverter::SKKRomanKanaConverter() {} + SKKRomanKanaConverter& SKKRomanKanaConverter::theInstance() { - static Node root; - static SKKRomanKanaConverter obj(root); + static SKKRomanKanaConverter obj; return obj; } -// Node ã®ã¤ã³ã¿ãã§ã¼ã¹ãé ãããã®è¦ããå®è£ -SKKRomanKanaConverter::SKKRomanKanaConverter(Node& node) : root_(node) { -} - void SKKRomanKanaConverter::Initialize(const std::string& path) { - std::ifstream rule(path.c_str()); + std::ifstream ifs(path.c_str()); std::string str; - if(!rule) { + if(!ifs) { std::cerr << "SKKRomanKanaConverter::Initialize(): can't open file [" << path << "]" << std::endl; return; } - // ã¯ãªã¢ + // åæåãã¦ãã root_.Clear(); - while(std::getline(rule, str)) { + while(std::getline(ifs, str)) { if(str.empty() || str[0] == '#') continue; // EUC-JP â UTF-8 å¤æ @@ -179,20 +80,20 @@ std::istringstream buf(utf8); // å¤æã«ã¼ã«ãèªã - std::string label, hirakana, katakana, jisx0201kana, next; - if(buf >> label >> hirakana >> katakana >> jisx0201kana) { + std::string roman, hirakana, katakana, jisx0201kana, next; + if(buf >> roman >> hirakana >> katakana >> jisx0201kana) { // ãªãã·ã§ã³ã®æ¬¡ç¶æ ãèªã buf >> next; // ã¨ã¹ã±ã¼ãæåãå ã«æ»ã - unescape_string(label); + unescape_string(roman); unescape_string(hirakana); unescape_string(katakana); unescape_string(jisx0201kana); unescape_string(next); - // 追å - root_.Add(label, Node(hirakana, katakana, jisx0201kana, next)); + // ã«ã¼ã«æ¨ã«è¿½å + root_.Add(roman, SKKRuleTreeNode(hirakana, katakana, jisx0201kana, next)); } else { // ä¸æ£ãªå½¢å¼ std::cerr << "SKKRomanKanaConverter::Initialize(): invalid rule [" << utf8 << "]" << std::endl; @@ -208,8 +109,8 @@ next.clear(); while(!str.empty()) { - int match_length; - const Node* node = root_.Traverse(str, match_length); + int state; + const SKKRuleTreeNode* node = root_.Traverse(str, state); // å¤æã§ããï¼ if(node) { @@ -221,19 +122,19 @@ } // é¨åçã«ä¸è´ãã¦ããããã¼ã¿ä¸è¶³ã®ãããã以ä¸å¦çã§ããªã - if(!match_length) { + if(!state) { next = str; return false; } - // æåã®ä¸æåãä¸è´ããªãå ´åãåºåã«ã³ãã¼ãã¦æ¬¡ã®æåã調ã¹ã - if(match_length < 0) { + // æåã®ä¸æåãæ¨ã«åå¨ããªãå ´åãåºåã«ã³ãã¼ãã¦æ¬¡ã®æåã調ã¹ã + if(state < 0) { out += str[0]; - match_length = 1; + state = 1; } - // ä¸è´ããé¨åãåãåã£ã¦æ¬¡ã®æåã調ã¹ã - str = str.substr(match_length); + // 調ã¹ãé¨åãåãåã£ã¦æ¬¡ã®æåã調ã¹ã + str = str.substr(state); } return converted; Index: AquaSKK/src/context/SKKRomanKanaConverter.h diff -u AquaSKK/src/context/SKKRomanKanaConverter.h:1.1.2.1 AquaSKK/src/context/SKKRomanKanaConverter.h:1.1.2.2 --- AquaSKK/src/context/SKKRomanKanaConverter.h:1.1.2.1 Sat Sep 8 22:35:18 2007 +++ AquaSKK/src/context/SKKRomanKanaConverter.h Sun Sep 9 11:59:49 2007 @@ -23,13 +23,12 @@ #include <string> #include "SKK.h" +#include "SKKRuleTreeNode.h" class SKKRomanKanaConverter { - class Node; - Node& root_; + SKKRuleTreeNode root_; SKKRomanKanaConverter(); - SKKRomanKanaConverter(Node& node); SKKRomanKanaConverter(const SKKRomanKanaConverter&); public: Index: AquaSKK/src/context/SKKRuleTreeNode.cpp diff -u /dev/null AquaSKK/src/context/SKKRuleTreeNode.cpp:1.1.2.1 --- /dev/null Sun Sep 9 11:59:49 2007 +++ AquaSKK/src/context/SKKRuleTreeNode.cpp Sun Sep 9 11:59:49 2007 @@ -0,0 +1,104 @@ +/* -*- C++ -*- + MacOS X implementation of the SKK input method. + + Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <iostream> +#include "SKKRuleTreeNode.h" + +SKKRuleTreeNode::SKKRuleTreeNode() : leaf_(false) { +} + +SKKRuleTreeNode::SKKRuleTreeNode(const std::string& hirakana, const std::string& katakana, + const std::string& jisx0201kana, const std::string& next) + : leaf_(true), hirakana_(hirakana), katakana_(katakana), jisx0201kana_(jisx0201kana), next_(next) { +} + +void SKKRuleTreeNode::Clear() { + children_.clear(); +} + +void SKKRuleTreeNode::Add(const std::string& str, const SKKRuleTreeNode& node, int depth) { + // æ«ç«¯ãï¼ + if(depth == str.size() - 1) { + children_[str[depth]] = node; + } else { + children_[str[depth]].Add(str, node, depth + 1); // å帰追å + } +} + +const SKKRuleTreeNode* SKKRuleTreeNode::Traverse(const std::string& str, int& state, int depth) { + // [1] ãã¼ã¿ä¸è¶³(ex. "k" ã "ch" ãªã©) + if(depth == str.size()) { + state = 0; + return 0; + } + + // ä¸è´ï¼ + if(children_.find(str[depth]) != children_.end()) { + SKKRuleTreeNode* node = &children_[str[depth]]; + + // æ«ç«¯ã§ãªããªãå帰æ¤ç´¢ + if(!node->children_.empty()) { + return node->Traverse(str, state, depth + 1); + } + + // [2] å®å ¨ä¸è´ + state = depth + 1; + return node; + } + + // [3] é¨åä¸è´(ex. "kb" ã "chm" ãªã©) + if(0 < depth) { + state = depth; + + // ç¯ãã¤èã§ããããnãã®ãããªå ´åã«ã¯ãä¸è´ã¨ãã¦æ±ã + if(leaf_) { + return this; + } + + return 0; + } + + // [4] æåã®ä¸æåãæ¨ã«åå¨ããªã + state = -1; + return 0; +} + +const std::string& SKKRuleTreeNode::KanaString(SKK::InputMode mode) const { + static std::string nothing; + + switch(mode) { + case SKK::Hirakana: + return hirakana_; + + case SKK::Katakana: + return katakana_; + + case SKK::Jisx0201Kana: + return jisx0201kana_; + + default: + std::cerr << "SKKRomanKanaConverter::Node::KanaString(): invalid mode [" << mode << "]" << std::endl; + return nothing; + } +} + +const std::string& SKKRuleTreeNode::NextState() const { + return next_; +} Index: AquaSKK/src/context/SKKRuleTreeNode.h diff -u /dev/null AquaSKK/src/context/SKKRuleTreeNode.h:1.1.2.1 --- /dev/null Sun Sep 9 11:59:49 2007 +++ AquaSKK/src/context/SKKRuleTreeNode.h Sun Sep 9 11:59:49 2007 @@ -0,0 +1,80 @@ +/* -*- C++ -*- + MacOS X implementation of the SKK input method. + + Copyright (C) 2007 Tomotaka SUWA <t.suw****@mac*****> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <string> +#include <map> +#include "SKK.h" + +#ifndef INC__SKKRuleTreeNode__ +#define INC__SKKRuleTreeNode__ + +// kana-rule-list ã®æ¨è¡¨ç¾ +class SKKRuleTreeNode { + bool leaf_; + std::string hirakana_; + std::string katakana_; + std::string jisx0201kana_; + std::string next_; + + std::map<char, SKKRuleTreeNode> children_; + +public: + SKKRuleTreeNode(); + SKKRuleTreeNode(const std::string& hirakana, const std::string& katakana, + const std::string& jisx0201kana, const std::string& next); + + // åæå + void Clear(); + + // å帰çãã¼ã追å + // + // å¼æ°ï¼ + // str=å¤ææåå + // node=追å ãã¼ã + // depth=æ¢ç´¢ã®æ·±åº¦(å帰å°ç¨) + // + // ä¾ï¼ + // node.Add("gya", SKKRuleTreeNode("ãã", "ã®ã£", "ï½·ï¾ï½¬", "")); + // + void Add(const std::string& str, const SKKRuleTreeNode& node, int depth = 0); + + // å帰çãã¼ãæ¤ç´¢ + // + // å¼æ°ï¼ + // str=å¤ææåå + // state=ç¶æ + // -1 æåã®ä¸æåãæ¨ã«åå¨ããªããã¨ã示ã + // 0 é¨åä¸è´ãã¦ãããã¨ã示ã(å¤æãåãåããããªã) + // 1 ä»¥ä¸ å¤ææååããåãåãæåæ°ã示ã(std::string::substr ã®å¼æ°) + // depth=æ¢ç´¢ã®æ·±åº¦(å帰å°ç¨) + // + // æ»ãå¤ï¼ + // å¤æçµæãã¼ãã¸ã®ãã¤ã³ã¿ãå¤æã§ããªãã£ãå ´å㯠0 + // + const SKKRuleTreeNode* Traverse(const std::string& str, int& state, int depth = 0); + + // ããªæåååå¾ + const std::string& KanaString(SKK::InputMode mode) const; + + // 次ç¶æ æåååå¾ + const std::string& NextState() const; +}; + +#endif