Created
June 14, 2012 00:08
-
-
Save nanofi/2927253 to your computer and use it in GitHub Desktop.
Call libmecab.dll from Ruby
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
require "dl/import" | |
#libmecab.dllのpathは自分で変えてね | |
module MecabImporter | |
extend DL::Importer | |
path = 'C:/Program Files (x86)/MeCab/bin/libmecab.dll' | |
dlload path | |
extern "mecab_t* mecab_new2(const char*)" | |
extern "const char* mecab_version()" | |
extern "const char* mecab_sparse_tostr(mecab_t*, const char*)" | |
extern "const char* mecab_strerror(mecab_t*)" | |
extern "const char * mecab_nbest_sparse_tostr(mecab_t *,unsigned long,const char *)" | |
extern "void mecab_destroy(mecab_t *)" | |
extern "int mecab_nbest_init(mecab_t*, const char*)" | |
extern "const char* mecab_nbest_next_tostr (mecab_t*)" | |
extern "mecab_node_t* mecab_sparse_tonode (mecab_t *, const char *)" | |
MecabNode = struct [ # サイズ取得 | |
"mecab_node_t* prev" , | |
"mecab_node_t* next", | |
"mecab_node_t* enext", | |
"mecab_node_t* bnext", | |
"mcab_path_t* rpath", | |
"mcab_path_t* lpath", | |
"char* surface", | |
"char* feature", | |
"unsigned int id", | |
"unsigned short length", | |
"unsigned short rlength", | |
"unsigned short rcAttr", | |
"unsigned short lcAttr", | |
"unsigned short posid", | |
"unsigned char char_type", | |
"unsigned char stat", | |
"unsigned char isbest", | |
"float alpha", | |
"float beta", | |
"float prob", | |
"short wcost", | |
"long cost" | |
] | |
MecabPath = struct [ # サイズ取得 | |
"void* rnode", | |
"void* rnext", | |
"void* lnode", | |
"void* lnext", | |
"int cost", | |
"float prob" | |
] | |
MECAB_NOR_NODE=0 | |
MECAB_UNK_NODE=1 | |
MECAB_BOS_NODE=2 | |
MECAB_EOS_NODE=3 | |
end | |
class Mecab | |
@mecab=nil | |
def initialize(args) | |
@mecab=MecabImporter.mecab_new2(args) | |
end | |
def version() | |
MecabImporter.mecab_version() | |
end | |
def strerror() | |
MecabImporter.mecab_strerror(@mecab) | |
end | |
def sparse_tostr(str) | |
MecabImporter.mecab_sparse_tostr(@mecab,str) | |
end | |
def nbest_sparse_tostr(nbest,str) | |
MecabImporter.mecab_nbest_sparse_tostr(@mecab,nbest,str) | |
end | |
def nbest_init(str) | |
MecabImporter.mecab_nbest_init(@mecab,str) | |
end | |
def nbest_next_tostr() | |
MecabImporter.mecab_nbest_next_tostr(@mecab) | |
end | |
def sparse_tonode(str) | |
Node.new MecabImporter.mecab_sparse_tonode(@mecab, str) | |
end | |
def destroy() | |
MecabImporter.mecab_destroy(@mecab) | |
end | |
class Node | |
def initialize(inner) | |
@prev, @next, @enext, @bnext, @rpath, @lpath, @surface, @feature, @id, @length, @rlength, @rcAttr, @lcAttr, @posid, @char_type, @stat, @isbest, @alpha, @beta, @prob, @wcost, @cost = inner.to_s(MecabImporter::MecabNode.size).unpack('L!8I!S!5C3f3s!l!') | |
end | |
def prev; Node.new DL::CPtr[@prev] unless @prev == 0 end | |
def next; Node.new DL::CPtr[@next] unless @next == 0; end | |
def enext; Node.new DL::CPtr[@enext] unless @enext == 0; end | |
def bnext; Node.new DL::CPtr[@bnext] unless @bnext == 0; end | |
def rpath; Path.new DL::CPtr[@rpath] unless @rpath == 0; end | |
def lpath; Path.new DL::CPtr[@lpath] unless @lpath == 0; end | |
def surface; DL::CPtr[@surface].to_s(@length) unless @surface == 0; end | |
def feature; DL::CPtr[@feature].to_s unless @feature == 0; end | |
attr_accessor :length, :rlength, :id, :rcAttr, :lcAttr, :posid, :char_type, :stat, :isbest, :alpha, :beta, :prob, :wcost, :cost | |
end | |
class Path | |
def initialize(inner) | |
@rnode, @rnext, @lnode, @lnext, @cost, @prob = inner.to_s(MecabImporter::MecabPath.size).unpack('L!4i!f') | |
end | |
def rnode; Node.new DL::CPtr[@rnode] unless @rnode == 0; end | |
def rnext; Path.new DL::CPtr[@rnext] unless @rnext == 0; end | |
def lnode; Node.new DL::CPtr[@lnode] unless @lnode == 0; end | |
def lnext; Path.new DL::CPtr[@lnext] unless @lnext == 0; end | |
attr_accessor :cost, :prob | |
end | |
end | |
#sample | |
#begin | |
# m=Mecab.new("") | |
# puts m.version | |
# puts m.sparse_tostr("本日は晴天なり") | |
# node = m.sparse_tonode("本日は晴天なり") | |
# while (node = node.next) | |
# print node.surface + " : " + node.posid.to_s + "\n" | |
# end | |
#ensure | |
# m.destroy | |
#end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment