[aquaskk-changes 364] CVS update: AquaSKK/src/context

Back to archive index

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


aquaskk-changes メーリングリストの案内
Back to archive index