ラオス語のテキストを音節に分割するために、C++ で ICU RuleBasedBreakIterator を使用しようとしています。ICU には、「同じであるが異なる」というタイ語の対応規則があります。SOLR の人々はJava で動作するものを持っていて、そこからルールを取得できますがRuleBasedBreakIterator
、コンストラクターを介して直接インスタンス化する方法の例を見つけることができませんBreakIterator
。これが私がこれまでに持っているもので、ICU docs からわずかに変更された関数です:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <unicode/unistr.h>
#include <unicode/rbbi.h>
#include <unicode/chariter.h>
using namespace std;
void listWordBoundaries(const UnicodeString&);
const char RULES[] = "";
int main(int argc, char *argv[]) {
listWordBoundaries(UnicodeString::fromUTF8("ປະເທດລາວ"));
}
void listWordBoundaries(const UnicodeString& s) {
UParseError parse_error;
UErrorCode status = U_ZERO_ERROR;
RuleBasedBreakIterator* bi = new RuleBasedBreakIterator(
UnicodeString::fromUTF8(RULES), parse_error, status
);
if(!U_SUCCESS(status)) {
fprintf(stderr, "Error creating RuleBasedBreakIterator\n"); // TODO print error
if(U_MESSAGE_PARSE_ERROR == status) {
fprintf(stderr, "Parse error on line %d offset %d\n", parse_error.line, parse_error.offset);
}
exit(1);
}
bi->setText(s);
int32_t p = bi->first();
while (p != BreakIterator::DONE) {
printf("Boundary at position %d (status %d)\n", p, bi->getRuleStatus());
p = bi->next();
}
delete bi;
}
ただし、bi->next
gdb によると、NULL 状態テーブルが原因で呼び出すとすぐにセグメンテーション違反が発生します。
Program received signal SIGSEGV, Segmentation fault.
icu_54::RuleBasedBreakIterator::handleNext (this=this@entry=0x614c70, statetable=0x0) at rbbi.cpp:1008
1008 UBool lookAheadHardBreak = (statetable->fFlags & RBBI_LOOKAHEAD_HARD_BREAK) != 0;
文字列は、上でリンクしRULES
たルールを保持することになっています。Lao.rbbi
空のルールセットでも効果は同じなので、ここでは省略しました。ルールに意味不明なものを入れると、if(!U_SUCCESS(status))
チェックは機能し、プログラムはエラーで終了するため、ルールの解析は機能しているように見えます。ただし、U_SUCCESS
戻りコードでさえ、反復子を適切に使用できることを示すには十分ではないようです。
私がここで見逃しているアイデアはありますか?