$Id: libmecab.html 65 2007-01-30 00:52:53Z taku-ku $;
C 라이브러리는 이하의 함수를 제공하고 있습니다.
mecab_t *mecab_new (int argc, char **argv)mecab_t *mecab_new2 (const char *arg)const char *mecab_version()const char *mecab_strerror (mecab_t* m)const char *mecab_sparse_tostr (mecab_t *m, const char
*str)const char *mecab_sparse_tostr2 (mecab_t *m, const char *str,
size_t len)char *mecab_sparse_tostr3 (mecab_t *m, const char
*istr,size_t ilen char *ostr, size_t olen)const char *mecab_nbest_sparse_tostr
(mecab_t *m, size_t N, const char *str)
const char *mecab_nbest_sparse_tostr2
(mecab_t *m, size_t N, const char *str, size_t len)
char *mecab_nbest_sparse_tostr3
(mecab_t *m, size_t N, const char *str, size_t len, char *ostr, size_t olen)
int mecab_nbest_init
(mecab_t* m, const char* str);
int mecab_nbest_init2
(mecab_t* m, const char* str, len);
const char *mecab_nbest_next_tostr
(mecab_t* m)
char *mecab_nbest_next_tostr2
(mecab_t *m , char *ostr, size_t olen)
void mecab_destroy(mecab_t *m)형태소 정보를 꺼내려면, 이하의 mecab_node_t 구조체와 mecab_sparse_tonode 함수를 사용합니다
#define MECAB_NOR_NODE 0
#define MECAB_UNK_NODE 1
#define MECAB_BOS_NODE 2
#define MECAB_EOS_NODE 3
struct mecab_node_t
{
struct mecab_node_t *prev; //
하나전의 형태소에의 포인터
struct mecab_node_t *next; //
하나처의 형태소에의 포인터
struct mecab_node_t *enext; //
같은 위치에서 끝나는 형태소에의 포인터
struct mecab_node_t *bnext; //
같은 개시 위치에서 시작되는 형태소에의 포인터
char *surface; //
형태소의 문자열 정보
// NULL terminate
되고 있지 않습니다.
문자열로서 꺼내려면
// strncpy(buf, node->feature, node->length)
(으)로 할 필요가 있습니다
char *feature; // CSV
그리고 표기된 태생 정보
unsigned int length; //
형태소의 길이
unsigned int rlength; //
형태소의 길이(
선두의 스페이스를 포함한다)
unsigned int id; //
형태소에 부여된다
유니크ID
unsigned short rcAttr; //
우문맥 id
unsigned short lcAttr; //
왼쪽 문맥 id
unsigned short posid; //
형태소 ID (
미사용)
unsigned char char_type; //
문자종 정보
unsigned char stat; //
형태소의 종류:
이하의 매크로의 값
// #define MECAB_NOR_NODE 0
// #define MECAB_UNK_NODE 1
// #define MECAB_BOS_NODE 2
// #define MECAB_EOS_NODE 3
unsigned char isbest; //
베스트해의 경우 1,
그 이외 0
float alpha; // forward backward
의 foward log
확률
float beta; // forward backward
의 backward log
확률
float prob; //
주변 확률
// alpha, beta, prob
하 -l 2
옵션을 지정했을 때에 정의됩니다
short wcost; //
단어 발생 코스트
long cost; //
누적 코스트
};
mecab_node_t *mecab_sparse_tonode (mecab_t *m, const char *str)mecab_node_t *mecab_sparse_tonode2 (mecab_t *m, const char *str,
size_t len)mecab_node_t *mecab_next_tonode
(mecab_t* m)
example/example.c
#include <mecab.h>
#include <stdio.h>
#define CHECK(eval) if (! eval) {
fprintf (stderr, "Exception:%sn", mecab_strerror (mecab));
mecab_destroy(mecab);
return -1; }
int main (int argc, char **argv)
{
char input[1024] = "
타로는 지로가 가지고 있는 책을 하나꼬에 건네주었다.";
mecab_t *mecab;
mecab_node_t *node;
const char *result;
int i;
mecab = mecab_new (argc, argv);
CHECK(mecab);
result = mecab_sparse_tostr(mecab, input);
CHECK(result)
printf ("INPUT: %sn", input);
printf ("RESULT:n%s", result);
result = mecab_nbest_sparse_tostr (mecab, 3, input);
CHECK(result);
fprintf (stdout, "NBEST:n%s", result);
CHECK(mecab_nbest_init(mecab, input));
for (i = 0; i < 3; ++i) {
printf ("%d:n%s", i, mecab_nbest_next_tostr (mecab));
}
node = mecab_sparse_tonode(mecab, input);
CHECK(node);
for (; node; node = node->next) {
fwrite (node->surface, sizeof(char), node->length, stdout);
printf("t%sn", node->feature);
}
node = mecab_sparse_tonode(mecab, input);
CHECK(node);
for (; node; node = node->next) {
printf("%d ", node->id);
if (node->stat == MECAB_BOS_NODE)
printf("BOS");
else if (node->stat == MECAB_EOS_NODE)
printf("EOS");
else
fwrite (node->surface, sizeof(char), node->length, stdout);
printf(" %s %d %d %d %d %d %d %d %d %f %f %f %dn",
node->feature,
(int)(node->surface - input),
(int)(node->surface - input + node->length),
node->rcAttr,
node->lcAttr,
node->posid,
(int)node->char_type,
(int)node->stat,
(int)node->isbest,
node->alpha,
node->beta,
node->prob,
node->cost);
}
mecab_destroy(mecab);
return 0;
}
이하가 C++ API 입니다. 기본적으로 C 의 interface와 동일합니다만,
그렇다고 하는 차이가 있습니다.
namespace MeCab
{
typedef struct mecab_node_t Node;
class Tagger
{
public:
virtual const char* parse(const char*, size_t, char*, size_t) = 0;
virtual const char* parse(const char*, size_t = 0) = 0;
virtual Node* parseToNode(const char*, size_t = 0) = 0;
virtual const char* parseNBest(size_t, const char*, size_t = 0) = 0;
virtual bool parseNBestInit(const char*, size_t = 0) = 0;
virtual Node* nextNode() = 0;
virtual const char* next() = 0;
virtual const char* formatNode(Node *) = 0;
virtual const char* next(char*, size_t) = 0;
virtual const char* parseNBest(size_t, const char*,
size_t, char *, size_t) = 0;
virtual const char* formatNode(Node *, char *, size_t) = 0;
virtual const char* what() = 0;
virtual Tagger() {};
static const char *version();
static Tagger* create(int, char**);
static Tagger* create(const char*);
};
/* factory method */
Tagger *createTagger (int, char**);
Tagger *createTagger (const char*);
const char* getTaggerError ();
}
#include <iostream>
#include <mecab.h>
#define CHECK(eval) if (! eval) {
const char *e = tagger ? tagger->what() : MeCab::getTaggerError();
std::cerr << "Exception:" << e << std::endl;
delete tagger;
return -1; }
int main (int argc, char **argv)
{
char input[1024] = "
타로는 지로가 가지고 있는 책을 하나꼬에 건네주었다.";
MeCab::Tagger *tagger = MeCab::createTagger (argc, argv);
CHECK(tagger);
const char *result = tagger->parse(input);
CHECK(result);
std::cout << "INPUT: " << input << std::endl;
std::cout << "RESULT: " << result << std::endl;
result = tagger->parseNBest(3, input);
CHECK(result);
std::cout << "NBEST: " << std::endl << result;
CHECK(tagger->parseNBestInit(input));
for (int i = 0; i < 3; ++i) {
std::cout << i << ":" << std::endl << tagger->next();
}
MeCab::Node* node = tagger->parseToNode(input);
CHECK(node);
for (; node; node = node->next) {
std::cout.write(node->surface, node->length);
}
node = tagger->parseToNode(input);
CHECK(node);
for (; node; node = node->next) {
std::cout << node->id << ' ';
if (node->stat == MECAB_BOS_NODE)
std::cout << "BOS";
else if (node->stat == MECAB_EOS_NODE)
std::cout << "EOS";
else
std::cout.write (node->surface, node->length);
std::cout << ' ' << node->feature
<< ' ' << (int)(node->surface - input)
<< ' ' << (int)(node->surface - input + node->length)
<< ' ' << node->rcAttr
<< ' ' << node->lcAttr
<< ' ' << node->posid
<< ' ' << (int)node->char_type
<< ' ' << (int)node->stat
<< ' ' << (int)node->isbest
<< ' ' << node->alpha
<< ' ' << node->beta
<< ' ' << node->prob
<< ' ' << node->cost << std::endl;
}
delete tagger;
return 0;
}
% cc -O2 `mecab-config --cflags` example.c -o example
`mecab-config --libs`
우선, 컴파일 작업을 실시하는 디렉토리에 includemecab.h, binlibmecab.dll liblibmecab.lib (을)를 카피합니다. 이 후의 작업은, 사용하는 컴파일러에 의해서 미묘하게 바뀝니다.
% gcc -DDLL_IMPORT -I. example.c -o example.exe libmecab.dll
% cl -DDLL_IMPORT -I. example.c libmecab.lib
MeCab 하, multi-thread 환경에서 사용하는 것이 가능합니다. 1 개의 스렛드에 1 인스턴스(mecab_t *) (을)를 할당하는 경우는 스렛드세이후입니다. 한층 더, 같은 사전을 계속 사용하는 한, 사전을 보관 유지하고 있는 자원은 재이용되기 위해, 복수의 인스턴스를 작성해도 많은 메모리를 사용할 것은 없습니다.
하나의 인스턴스를 복수의 스렛드로부터 사용하는 경우는 적당하게 배타 제어할 필요가 있습니다. 다만, 퍼포먼스가 나쁘기 때문에 추천할 수 없습니다.
$Id: libmecab.html 65 2007-01-30 00:52:53Z taku-ku $;