Last active
December 25, 2015 11:59
-
-
Save shiumachi/6972974 to your computer and use it in GitHub Desktop.
#gocon 2013 Autumn での成果物。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* go のコンパイル | |
brew のインストールファイルにはファイルが欠けているものがあるので、ソースから go をビルドする必要がある | |
ソースは以下のコマンドでとってこれる。 | |
$ hg clone -u release https://code.google.com/p/go | |
GOROOTの変更を忘れずに。 | |
$ GOROOT=${HOME}/src/go | |
mecab とのリンクには 32bit アーキテクチャでコンパイルする必要がある。 | |
(注: 後でコンパイルしたらアーキテクチャ指定しなくてもよかったので、実はいらない可能性がある。ここでは記録のため残しておく) | |
$ cd $GOROOT/src | |
$ GOARCH=386 bash make.bash | |
$ bash make.bash | |
(x86_64 用。こうするとこっちがデフォルトになる) | |
これでx86用コンパイラができる。 | |
コンパイルは以下のように行う。 | |
# GOARCH=386 go build | |
ソースコードからのコンパイルは下記リンクを参照 | |
http://golang.org/doc/install/source | |
* mecab のコンパイル | |
mecab のコンパイルにはいくつかのオプションが必要。 | |
http://mecab.googlecode.com/svn/trunk/mecab/doc/libmecab.html | |
ここを参照に、以下のコマンドを実行する。 | |
$ mecab-config --cflags | |
-I/usr/local/Cellar/mecab/0.996/include | |
$ mecab-config --libs | |
-L/usr/local/Cellar/mecab/0.996/lib -lmecab -lstdc++ | |
これらを go 内の C のコードに追加する。 | |
/* | |
#cgo CFLAGS: -I/usr/local/Cellar/mecab/0.996/include | |
#cgo LDFLAGS: -L/usr/local/Cellar/mecab/0.996/lib -lmecab -lstdc++ | |
#include <mecab.h> | |
struct mecab_t {}; | |
*/ | |
import "C" | |
これを設定したら、go install でコンパイルする。 | |
CGO_ENABLED=1 go install ./mecab-bin | |
* cgo の基本 | |
/* | |
C のコード …. | |
*/ | |
import "C" | |
という風にコメントに書く。今回使うコードは先述の通り。 | |
C.(型、関数、構造体) の形式でほとんど何でも使える。 | |
例: | |
C.mecab_new2(ptr) | |
C と Go の間でプリミティブ型に全て互換性があるわけじゃないので、データのやりとりには型変換が必要。 | |
文字列の場合 | |
Go から C | |
p := C.CString(s) | |
C から Go | |
ret_val := C.GoString(ptr) | |
int型 | |
C から Go | |
int(c_int) | |
* cgo のコンパイル | |
なぜか main 関数が同一パッケージだとコンパイルできないので注意 | |
(他に方法があるかもしれないが分からなかった) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import "fmt" | |
import "mecab" | |
import "os" | |
func main() { | |
fmt.Printf("hello, world\n") | |
var s2 string | |
if len(os.Args) != 2 { | |
fmt.Printf("usage: mecab-bin [string]\n") | |
s2 = "今日、僕は新橋でビール片手に壁を上った。" | |
} else { | |
s2 = os.Args[1] | |
} | |
m := mecab.New2("") | |
fmt.Printf("--- SparseToStr ---\n") | |
r := mecab.SparseToStr(m, s2) | |
fmt.Printf("result: \n%s\n", r) | |
fmt.Printf("--- NBestSparseToStr(num: 3) ---\n") | |
r = mecab.NBestSparseToStr(m, 3, s2) | |
fmt.Printf("result: \n%s\n", r) | |
fmt.Printf("--- DumpNode ---\n") | |
n := mecab.SparseToNode(m, s2) | |
mecab.DumpNode(n) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package mecab | |
import "fmt" | |
/* | |
#cgo CFLAGS: -I/usr/local/Cellar/mecab/0.996/include | |
#cgo LDFLAGS: -L/usr/local/Cellar/mecab/0.996/lib -lmecab -lstdc++ | |
#include <mecab.h> | |
struct mecab_t {}; | |
*/ | |
import "C" | |
func New2(s string) *C.mecab_t { | |
p := C.CString(s) | |
m := C.mecab_new2(p) | |
return m | |
} | |
/* | |
http://mecab.googlecode.com/svn/trunk/mecab/doc/libmecab.html | |
// Gets tagged result in string. | |
result = mecab_sparse_tostr(mecab, input); | |
CHECK(result) | |
printf ("INPUT: %s\n", input); | |
printf ("RESULT:\n%s", result); | |
*/ | |
func SparseToStr(m *C.mecab_t, s string) string { | |
p := C.CString(s) | |
r := C.mecab_sparse_tostr(m, p) | |
ret_val := C.GoString(r) | |
return ret_val | |
} | |
/* | |
http://mecab.googlecode.com/svn/trunk/mecab/doc/libmecab.html | |
// Gets N best results | |
result = mecab_nbest_sparse_tostr (mecab, 3, input); | |
CHECK(result); | |
fprintf (stdout, "NBEST:\n%s", result); | |
*/ | |
func NBestSparseToStr(m *C.mecab_t, num int, input string) string { | |
p := C.CString(input) | |
c_num := C.size_t(num) | |
r := C.mecab_nbest_sparse_tostr(m, c_num, p) | |
ret_val := C.GoString(r) | |
return ret_val | |
} | |
/* | |
http://mecab.googlecode.com/svn/trunk/mecab/doc/libmecab.html | |
node = mecab_sparse_tonode(mecab, input); | |
CHECK(node); | |
for (; node; node = node->next) { | |
if (node->stat == MECAB_NOR_NODE || node->stat == MECAB_UNK_NODE) { | |
fwrite (node->surface, sizeof(char), node->length, stdout); | |
printf("\t%s\n", node->feature); | |
} | |
} | |
*/ | |
func SparseToNode(m *C.mecab_t, input string) *C.mecab_node_t { | |
p := C.CString(input) | |
node := C.mecab_sparse_tonode(m, p) | |
return node | |
} | |
/* | |
http://www.mwsoft.jp/programming/nlp/mecab_cpp.html | |
for (; node; node = node->next) { | |
std::cout << "==========" << std::endl; | |
std::cout << "id : " << node->id << std::endl; | |
std::cout << "surface : " << node->surface << std::endl; | |
std::cout << "feature : " << node->feature << std::endl; | |
std::cout << "length : " << node->length << std::endl; | |
std::cout << "rlength : " << node->rlength << std::endl; | |
std::cout << "rcAttr : " << node->rcAttr << std::endl; | |
std::cout << "lcAttr : " << node->lcAttr << std::endl; | |
std::cout << "posid : " << node->posid << std::endl; | |
std::cout << "char_type : " << (int)node->char_type << std::endl; | |
std::cout << "stat : " << (int)node->stat << std::endl; | |
std::cout << "isbest : " << (int)node->isbest << std::endl; | |
std::cout << "alpha : " << node->alpha << std::endl; | |
std::cout << "beta : " << node->beta << std::endl; | |
std::cout << "prob : " << node->prob << std::endl; | |
std::cout << "wcost : " << node->wcost << std::endl; | |
std::cout << "cost : " << node->cost << std::endl; | |
} | |
========== | |
id : 0 | |
surface : 昼寝する | |
feature : BOS/EOS,*,*,*,*,*,*,*,* | |
length : 0 | |
rlength : 0 | |
rcAttr : 0 | |
lcAttr : 0 | |
posid : 0 | |
char_type : 0 | |
stat : 2 | |
isbest : 1 | |
alpha : 0 | |
beta : 0 | |
prob : 0 | |
wcost : 0 | |
cost : 0 | |
*/ | |
func DumpNode(n *C.mecab_node_t) { | |
fmt.Printf("id: %d\n", int(n.id)) | |
fmt.Printf("surface: %s\n", C.GoString(n.surface)) | |
fmt.Printf("feature: %s\n", C.GoString(n.feature)) | |
fmt.Printf("length: %d\n", int(n.length)) | |
fmt.Printf("rlength: %d\n", int(n.rlength)) | |
fmt.Printf("rcAttr: %d\n", int(n.rcAttr)) | |
fmt.Printf("lcAttr: %d\n", int(n.lcAttr)) | |
fmt.Printf("posid: %d\n", int(n.posid)) | |
fmt.Printf("char_type: %d\n", int(n.char_type)) | |
fmt.Printf("stat: %d\n", int(n.stat)) | |
fmt.Printf("isbest: %d\n", int(n.isbest)) | |
fmt.Printf("alpha: %d\n", int(n.alpha)) | |
fmt.Printf("beta: %d\n", int(n.beta)) | |
fmt.Printf("wcost: %d\n", int(n.wcost)) | |
fmt.Printf("cost: %d\n", int(n.cost)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment