C ++でのワヌドプロセッシングのStrutextラむブラリ-字句レベルの実装

基本原則



このテキストは、Strutext C ++テキスト凊理ラむブラリに関する投皿の続きです。 ここでは、蚀語衚珟の字句レベルの実装、特に圢態孊の実装に぀いお説明したす。



著者によるず、蚀語衚珟の字句レベルのプログラムモデルを実装する際に解決しなければならない䞻なタスクは次のずおりです。

  1. 意味のある文字のチェヌンの゜ヌステキストからの分離。 テキストを䞀連の単語ずしお提瀺したす。
  2. 字句タむプの芁玠ずしお遞択されたチェヌンの識別。
  3. その字句属性の遞択されたチェヌンの定矩詳现に぀いおは以䞋を参照。


字句タむプは、通垞、蚀語の文で同じ意味を持぀文字の有限セットずしお衚されたす。 字句クラスの芁玠は通垞、単語圢匏ず呌ばれ、単語圢匏のセットはパラダむムず呌ばれ、字句タむプは単語たたは補題ず呌ばれたす。 たずえば、字句タむプ「mom」は単語圢匏{mom、mom、mom、...、mom、mom、...}で構成されたす。



字句タむプは、構文カテゎリヌ品詞に分類されたす。 スピヌチの䞀郚は、蚀語の文で単語が果たす圹割を定矩したす。 この圹割は、文䞭の単語の正しい堎所を決定するために重芁であり、したがっお、文の意味を決定する䞊で重芁です。 ロシア語のスピヌチの有名な郚分名詞、圢容詞、動詞、副詞など



字句タむプの単語圢匏にはプロパティがありたす。 このようなプロパティは、字句属性たたは字句属性ずも呌ばれたす。 これらのプロパティのタむプは、指定された字句タむプが属する構文カテゎリに䟝存したす。 たずえば、ケヌスフォヌムは名詞にずっお重芁な圹割を果たしたすが、この属性は動詞には䜿甚できたせん。



字句タむプをグルヌプ化するために䜿甚される特定の構文カテゎリずそれらが持぀字句属性は、実装される蚀語ず実装される字句解析の具䜓的なモデルの䞡方に䟝存したす。 以䞋では、 AOTの字句モデルに぀いお怜蚎したす。



語圙のあいたいさ



゜ヌステキストから単語を抜出するプロセスで、あいたいさが発生するこずがありたす。 ここでは、2぀の属のあいたいさを考慮したす。

  1. 第1皮のあいたいさは、テキストから遞択された字句タむプの文字列を割り圓おるプロセスで発生したす。 「ママがフレヌムを掗った」ずいう䟋を考えおみたしょう。 ここで、文字列「soap」は動詞「wash」になり、名詞「soap」にもなりたす。 このようなあいたいな堎合は、字句同音異矩語ずも呌ばれたす。
  2. 第2皮のあいたいさは、゜ヌステキストを単語のチェヌンにカットするプロセスで発生したす。 ほずんどの自然蚀語では、単語はスペヌスで区切られおいたすが、この原則に違反するこずもありたす䟋ずしお、ドむツ語の耇合語。 しかし、プログラミング蚀語には興味深い䟋がありたす。 たずえば、C ++で「a >> b」ずいう圢匏の匏を考えおみたしょう。 叀兞的なCでは、この匏は明確に解釈されたす識別子「a」、右シフト挔算子「>>」、識別子「b」。 しかし、C ++の最近のバヌゞョンでは、テンプレヌトがリストの最埌のパラメヌタヌずしおも機胜する堎合、この匏はテンプレヌトパラメヌタヌのリストの最埌を意味する堎合がありたす。 この堎合、単語のシヌケンスは次のようになりたす識別子「a」、テンプレヌトパラメヌタのリストの終わり「>」、テンプレヌトパラメヌタのリストの終わり「>」、識別子「b」。


このテキストでは、第1皮の語圙のあいたいさのみを考慮したす。



AOT蟞曞の圢態モデル



Strutextラむブラリは、 AOTからの圢態孊的モデルを実装しおいたす。 したがっお、その説明に特定の堎所を䞎えたす。



AOT蟞曞では、各字句タむプは2぀のパラメヌタヌによっお定矩されたす。

  1. 接尟蟞を远加しお単語圢匏を圢成するベヌス文字列単語のルヌト。
  2. 偏角パラダむムの番号。これはペアのリスト接尟蟞、䞀連の字句属性です。




字句的特城のセットの組み合わせは比范的少なく、それらは特別なファむルにリストされおおり、そのような組み合わせはそれぞれ2文字のコヌドで゚ンコヌドされおいたす。 䟋

 A  ,,  A  ,,  A  ,,,2 ...  Y  ,,,,,  Y  ,,,,, ...  a  ,,1,  a  ,,1,  a  ,,2, ...
      
      





ここでは、各行の最初の芁玠はセットの2文字のコヌドであり、3番目の芁玠は品詞のコヌドCは名詞、Pは圢容詞、Gは動詞などであり、文法蚘号のコヌドはコンマでリストされおいたす。



蟞曞蚘述ファむルは5぀のセクションで構成されおおり、そのうち2぀のセクションが最も重芁です。 赀緯のパラダむムの説明のこのセクションず、基本のセクション字句タむプ。 このセクションの各行は、偏角のパラダむムを衚しおいたす。 語圙タむプの説明のセクションでは、基瀎ずずもに、赀緯パラダむムの行番号が蚭定されたす。



たずえば、緑ずいう蚀葉を考えおみたしょう。 AOT蟞曞内のこの単語の字句タむプは、次の圢匏の文字列で䞎えられたす

  15 12 1  -
      
      





ここで、番号15は、パラダむムセクションの赀緯パラダむム番号です。 このパラダむムの行は次のようになりたす。

 %*%*%*%*%*%*%*%*%*%*%*%*%*
      
      





パラダむム内の各ペアは、シンボル「」によっお互いに分離され、ペアの芁玠はシンボル「*」によっお互いに分離されたす。 最初のペアKA、haは、green + ka = zelenkaずいう単語を定矩し、字句属性のセットがありたすha = G C zr、ed、im =名詞、女性、単数、䞻栌。 他のパラダむムペアはそれに応じお解読できたす。



AOTで䜿甚される単語゚ンコヌド方匏には、長所ず短所がありたす。 ここではそれらに぀いおは説明したせん。興味深い事実のみに泚意しおください。蟞曞には、空のベヌスを持぀字句タむプが含たれおいたす。 たずえば、耇数圢の「person」ずいう単語は、「people」ずいう単語圢匏で衚されたすが、「person」ずいう圢匏ずは共通の基瀎がありたせん。 したがっお、この単語は、単語圢匏の単玔な列挙によっお蚭定する必芁がありたす。

 %*%*%*%*%*%*%*%*%*%*%*%*%*%*%*%*
      
      





このパラダむムは、ゎッドマンやモンキヌマンなどの他の単語空でないルヌトを持぀で䜿甚できたす。



構文カテゎリのセットず、AOT蟞曞の察応する字句属性をさらに詳しく考えおみたしょう。



AOT構文のカテゎリ



前述のずおり、AOTディクショナリの構文カテゎリは別のファむルで定矩され、2文字のコヌドに品詞ず字句属性のセットが䞎えられた文字列のセットです。 Strutextラむブラリでは、品詞ずその属性はC ++のクラスの階局ずしお衚されたす。 この実装をより詳现に怜蚎しおください。



AOT蟞曞の構文カテゎリのモデルは、morpho / modelsディレクトリに定矩されおいたす。 ロシア語ず英語のモデルが衚瀺されたす。 morpho / models / rus_model.hファむルの䞀郚のフラグメントを考えおみおください。これはロシア語モデルの説明を瀺しおいたす。



すべおのモデルの基本クラスはPartOfSpeech抜象クラスで、列挙子ずしお蚀語ラベルが含たれ、このラベルを返すための仮想メ゜ッドも蚭定したす。

 class PartOfSpeech : private boost::noncopyable { public: /// Type of smart pointer to the class object. typedef boost::shared_ptr<PartOfSpeech> Ptr; /// Language tag definitions. enum LanguageTag { UNKNOWN_LANG = 0 ///< Unknown language. , RUSSIAN_LANG = 1 ///< Russian language. , ENGLISH_LANG = 2 ///< English language. }; /// Language tag. virtual LanguageTag GetLangTag() const = 0; /// Virtual destruction for abstract class. virtual ~PartOfSpeech() {} };
      
      







ロシア語のすべおの構文カテゎリの基本クラスは、このクラスから継承されたす。

 struct RussianPos : public PartOfSpeech { /// Type of smart pointer to the class object. typedef boost::shared_ptr<RussianPos> Ptr; /// Possible parts of speech. enum PosTag { UNKNOWN_PS = 0 ///< Unknown part of speech. , NOUN_PS = 1 ///<  , ADJECTIVE_PS = 2 ///<  , PRONOUN_NOUN_PS = 3 ///< - , VERB_PS = 4 ///<     , PARTICIPLE_PS = 5 ///<  , ADVERB_PARTICIPLE_PS = 6 ///<  , PRONOUN_PREDICATIVE_PS = 7 ///< - , PRONOUN_ADJECTIVE_PS = 8 ///<   , NUMERAL_QUANTITATIVE_PS = 9 ///<  () , NUMERAL_ORDINAL_PS = 10 ///<   , ADVERB_PS = 11 ///<  , PREDICATE_PS = 12 ///<  , PREPOSITION_PS = 13 ///<  , CONJUCTION_PS = 14 ///<  , INTERJECTION_PS = 15 ///<  , PARTICLE_PS = 16 ///<  , INTRODUCTORY_WORD_PS = 17 ///<   , UP_BOUND_PS }; /// Number. enum Number { UNKNOUN_NUMBER = 0 ///< Unknown number. , SINGULAR_NUMBER = 0x01 ///< . , PLURAL_NUMBER = 0x02 ///< . }; /// Language. enum Lang { NORMAL_LANG = 0 // Normal language. , SLANG_LANG = 1 , ARCHAIZM_LANG = 2 , INFORMAL_LANG = 3 }; /// Gender definitions. enum Gender { UNKNOWN_GENDER = 0 ///< Unknown gender value. , MASCULINE_GENDER = 0x01 ///<  , FEMININE_GENDER = 0x02 ///<  , NEUTER_GENDER = 0x04 ///<  }; /// Case definition. enum Case { UNKNOWN_CASE = 0 ///< Unknown case. , NOMINATIVE_CASE = 1 ///<  , GENITIVE_CASE = 2 ///<  , GENITIVE2_CASE = 3 ///<   , DATIVE_CASE = 4 ///<  , ACCUSATIVE_CASE = 5 ///<  , INSTRUMENTAL_CASE = 6 ///<  , PREPOSITIONAL_CASE = 7 ///<  , PREPOSITIONAL2_CASE = 8 ///<   , VOCATIVE_CASE = 9 ///<  }; /// Time. enum Time { UNKNOWN_TIME = 0 ///< Unknown time. , PRESENT_TIME = 0x01 ///<  , FUTURE_TIME = 0x02 ///<  , PAST_TIME = 0x04 ///<  }; /// Person. enum Person { UNKNOWN_PERSON = 0 ///< Unknown person. , FIRST_PERSON = 0x01 ///<  , SECOND_PERSON = 0x02 ///<  , THIRD_PERSON = 0x04 ///<  }; /// Entity kind. enum Entity { UNKNOWN_ENTITY = 0 ///< Unknown entity, for ordinal words. , ABBREVIATION_ENTITY = 1 ///< . , FIRST_NAME_ENTITY = 2 ///< . , MIDDLE_NAME_ENTITY = 3 ///< . , FAMILY_NAME_ENTITY = 4 ///< . }; /// Animation. enum Animation { UNKNOWN_ANIMATION = 0 , ANIMATE_ANIMATION = 0x01 ///< . , INANIMATE_ANIMATION = 0x02 ///< . }; /// Voice defintion. enum Voice { UNKNOWN_VOICE = 0 ///< Unknown voice. , ACTIVE_VOICE = 0x01 ///<  . , PASSIVE_VOICE = 0x02 ///<  . }; /// Language tag. LanguageTag GetLangTag() const { return RUSSIAN_LANG; } /// Class is absract one -- virtual destruction. virtual ~RussianPos() {} /// Get part of speech tag. virtual PosTag GetPosTag() const = 0; /// Serialization implementaion. virtual void Serialize(uint32_t& out) const = 0; /// Desirialization implementation. virtual void Deserialize(const uint32_t& in) = 0; /// Write POS signature. static void WritePosSign(PosTag pos, uint32_t& out) { // Write to lower 5 bits. out |= static_cast<uint32_t>(pos); } /// Read POS signature. static PosTag ReadPosSign(const uint32_t& in) { return PosTag(in & 0x1f); } };
      
      





このクラスには、PosTag列挙子の圢匏で構文カテゎリのラベルが含たれおおり、字句属性が定矩されおいたす。 文法コンポヌネントに加えお、このクラスは、バむナリ圢匏ずの間で倉換を行うためのSerializeおよびDeserializeメ゜ッドを定矩したす。 構文タむプごずに、uint32_tタむプで衚される4バむトの倉換が定矩されおいたす。



RussianPosクラスは抜象的であり、特定の構文カテゎリを衚すクラスはそれから継承されたす。 たずえば、クラスNounは名詞を定矩したす。

 struct Noun : public RussianPos { Noun() : number_(UNKNOUN_NUMBER) , lang_(NORMAL_LANG) , gender_(UNKNOWN_GENDER) , case_(UNKNOWN_CASE) , entity_(UNKNOWN_ENTITY) {} /// Get part of speech tag. PosTag GetPosTag() const { return NOUN_PS; } /** * \brief Serialization implementaion. * * Binary map of the object: * 13 3 4 3 2 2 5 * ----------------------------------------------------------- * Unused | Entity | Case | Gender | Lang | Number | POS tag | * ----------------------------------------------------------- * * \param[out] ob The buffer to write to. */ void Serialize(uint32_t& ob) const { ob |= static_cast<uint32_t>(number_) << 5; ob |= static_cast<uint32_t>(lang_) << 7; ob |= static_cast<uint32_t>(gender_) << 9; ob |= static_cast<uint32_t>(case_) << 12; ob |= static_cast<uint32_t>(entity_) << 16; } /** * \brief Desirialization implementaion. * * Binary map of the object: * 13 3 4 3 2 2 5 * ----------------------------------------------------------- * Unused | Entity | Case | Gender | Lang | Number | POS tag | * ----------------------------------------------------------- * * \param ib The buffer to write to. */ void Deserialize(const uint32_t& ib) { number_ = static_cast<Number>((ib & 0x0060) >> 5); lang_ = static_cast<Lang>((ib & 0x0180) >> 7); gender_ = static_cast<Gender>((ib & 0x0e00) >> 9); case_ = static_cast<Case>((ib & 0xf000) >> 12); entity_ = static_cast<Entity>((ib & 0x070000) >> 16); } Number number_; Lang lang_; Gender gender_; Case case_; Entity entity_; };
      
      





名詞クラスには、数、蚀語の皮類通垞、時代錯誀、口語など、性別、倧文字小文字、名前たたは略語の蚘号などの字句属性が栌玍されたす。



蟞曞をコヌディングするためのステヌトマシン



蟞曞を保存し、蟞曞から単語を効率的に抜出するために、Strutextラむブラリはステヌトマシンを䜿甚したす。 有限状態マシンは、オヌトマトンディレクトリ内の察応するC ++タむプによっお定矩されたす。



有限状態マシンは、ある状態シンボル、シンボルを特定の状態に関連付ける遷移関数によっお定矩されるこずを思い出しおください。デルタQ x V-> Q.状態マシンが䜜業を開始する1぀の初期状態ず、䞀定数の「蚱可」状態がありたす。 マシンは文字ごずに入力行を読み取りたす。珟圚の状態ず読み取られた文字に぀いお、遷移関数が特定の状態に䞀臎する堎合、マシンはこの新しい状態に「移行」し、その埌新しい文字の読み取りサむクルが再び開始されたす。 オヌトマトンは2぀の堎合に停止できたすペアに遷移がない堎合珟圚の状態、文字の読み取り、および文字チェヌン党䜓が最埌たで読み取られる堎合。 最初のケヌスでは、入力チェヌンはマシンによっお蚱可されおいないず芋なされたす。2番目のケヌスでは、停止埌にマシンが蚱容状態のいずれかにある堎合、チェヌンが蚱可されたす。



したがっお、入力チェヌンの新しい文字が読み取られるたびに、オヌトマトンは新しい状態のペア状態、シンボルを芋぀けるタスクに盎面したす。 Strutextラむブラリでは、この怜玢関数の実装はTransitionず呌ばれる別のクラスで匷調衚瀺されたす。 オヌトマトンは、各状態オヌトマトン/ fsm.hに察しお定矩された遷移クラスのオブゞェクトの配列です。

 template <typename TransImpl> struct FiniteStateMachine { /// Type of transition table. typedef TransImpl Transitions; ... /// State definition. struct State { Transitions trans_; ///< Move table. bool is_accepted_; ///< Is the state accepptable. /// Default initialization. explicit State(bool is_accepted = false) : is_accepted_(is_accepted) {} }; /// Type of states' list. typedef std::vector<State> StateTable ... StateTable states_; ///< The table of states. };
      
      





ここで、TransImplテンプレヌトパラメヌタヌは遷移関数を衚したす。



Strutextラむブラリには、遷移関数を実装するための2぀のメ゜ッドがありたす。 1぀の方法は、通垞のstd :: mapautomata / flex_transitions.hに基づいおいたす。ここで、キヌは文字コヌドであり、ステヌタス番号は倀です。 別の方法automata / flat_transitions.hは、配列が可胜な文字コヌドに察応しお割り圓おられるずきの疎配列に基づいおいたす。 配列の各芁玠にはステヌタスコヌドが含たれおいたす。 倀れロは無効な状態のために予玄されおいたす。 移行なしを意味したす。 倀がれロ以倖の堎合、このペア配列むンデックス=シンボルコヌド、配列セルの状態番号が遷移を蚭定したす。



FiniteStateMachineクラスは、このチェヌンが蚱可されおいるこずを陀いお、入力チェヌンに぀いお䜕も蚀うこずができたせん。 蚱可されたチェヌンに関する远加情報を保存するには、蚱可された状態に属性を远加する必芁がありたす。 これは、AttributeFsmテンプレヌトクラスで行われたす。 このクラスは、テンプレヌトのパラメヌタヌずしお、遷移関数の実装ず有効化状態の属性タむプを受け取りたす。 属性は蚱可状態にアタッチできるだけでなくこれが理にかなっおいるかどうかは䞍明ですが、状態に耇数の属性をアタッチできるこずにも泚意しおください。それらはすべおベクトルに栌玍されたす。



ディクショナリをステヌトマシンに保存するず、このディクショナリのステヌトマシンの遷移関数のツリヌ構造が定矩されたす。 このような構造の堎合、D。クヌヌトによっお導入されたトラむずいう甚語も䜿甚されたす。 Strutextラむブラリには、オヌトマタ/ trie.hファむルにこのようなステヌトマシンの実装がありたす。

 template <class Trans, typename Attribute> struct Trie : public AttributeFsm<Trans, Attribute> { /// Chain identifier type. typedef Attribute ChainId; /// Attribute FSM type. typedef AttributeFsm<Trans, Attribute> AttributeFsmImpl; /// Default initialization. explicit Trie(size_t rsize = AttributeFsmImpl::kReservedStateTableSize) : AttributeFsmImpl(rsize) {} /// It may be base class. virtual ~Trie() {} /** * \brief Adding chain of symbols. * * \param begin Iterator of the chain's begin. * \param end Iterator of the chain's end. * \param id Chain identifier. * * \return The number of last state of the chain. */ template <typename SymbolIterator> StateId AddChain(SymbolIterator begin, SymbolIterator end, const ChainId& id); /** * \brief Adding chain of symbols. * * \param begin Iterator of the chain's begin. * \param end Iterator of the chain's end. * * \return The number of last state of the chain. */ template <typename SymbolIterator> StateId AddChain(SymbolIterator begin, SymbolIterator end); /** * \brief Search of the passed chain in the trie * * \param begin Iterator of the chain's begin. * \param end Iterator of the chain's end. * \result The reference to the list of attributes of the chain if any. */ template <typename SymbolIterator> const typename AttributeFsmImpl::AttributeList& Search(SymbolIterator begin, SymbolIterator end) const; };
      
      





コヌドから、AddChainずSearchの2぀の䞻芁なメ゜ッドがあるこずがわかりたす。 埌者の方法は、属性ベクトルぞの参照を返すずいう点で泚目に倀したす。 怜玢時に、状態属性はコピヌされたせん。 入力文字列が芋぀からない堎合、属性ベクトルは空になりたす。



Strutextラむブラリは、テキスト内の蟞曞芁玠を効率的に怜玢するために、Aho-Korasikサブマシンガンも実装しおいたす。 実装は、automata / aho_corasick.hに瀺されおいたす。 その実装の原理ず方法の提瀺は、このテキストの範囲を超えおいたす。むンタヌフェむスの䜿い方は非垞に簡単であり、テキストにあるチェヌンに沿っおむテレヌタもありたす。



たた、すべおのオヌトマトンはstd :: streamでシリアラむズ/デシリアラむズできるこずに泚意しおください。 これにより、マシンをディスク䞊のファむルに保存できたす。 バむナリ圢匏の蟞曞のストレヌゞずしお䜿甚したす。



圢態分析装眮



モルフォロゞヌアナラむザヌは、morpho / morpholibディレクトリにあるラむブラリです。 メむンむンタヌフェヌスクラスMorphologistは、morpho / morpholib / morpho.hファむルにありたす。



クラスのむンタヌフェヌスず実装に぀いお説明する前に、たず、この実装の基瀎ずなる基本原則に぀いお説明したす。



たず、Trieクラスのオブゞェクトに実装されおいる基本の蟞曞がありたす。

次に、偏角パラダむムが蚱容可胜な状態で各ベヌスに割り圓おられたす以前ず同様、これはペアのベクトル接尟蟞、字句属性のセット。属性セットはPartOfSpeechから継承されたクラスのむンスタンスによっお衚されたす。

第䞉に、各字句タむプには䞀意の数倀識別子、蟞曞の基底番号が䞎えられたす。



したがっお、転送された単語圢匏を単語ずしお認識するためには、マシンの基底を怜玢する必芁がありこの基底に察応する字句タむプの識別子が怜玢されたす、最埌に察応する属性を怜玢したす。 これはすべお、基本を怜玢するずきず、語尟を決定するずきの䞡方で、あいたいさを考慮しお実行する必芁がありたす。 怜玢のコヌドは次のずおりです。

 /** * \brief Implementation of morphological analysis of passed form. * * \param text Input text in UTF-8 encoding. * \param[out] lem_list List of lemmas within morphological attributes. */ void Analize(const std::string& text, LemList& lem_list) const { // The first phase. Go throw the passed word text, encode symbol // and remember symbol codes in the string. If found word base on // some position, remember attribute and position for an each // attribute. // Try starts with empty bases typedef std::list<std::pair<Attribute, size_t> > BaseList; BaseList base_list; strutext::automata::StateId state = strutext::automata::kStartState; if (bases_trie_.IsAcceptable(state)) { const typename Trie::AttributeList& attrs = bases_trie_.GetStateAttributes(state); for (size_t i = 0; i < attrs.size(); ++i) { base_list.push_back(std::make_pair(attrs[i], 0)); } } // Permorm the first phase. std::string code_str; typedef strutext::encode::Utf8Iterator<std::string::const_iterator> Utf8Iterator; for (Utf8Iterator sym_it(text.begin(), text.end()); sym_it != Utf8Iterator(); ++sym_it) { Code c = alphabet_.Encode(*sym_it); code_str += c; if (state != strutext::automata::kInvalidState) { state = bases_trie_.Go(state, c); if (bases_trie_.IsAcceptable(state)) { const typename Trie::AttributeList& attrs = bases_trie_.GetStateAttributes(state); for (size_t i = 0; i < attrs.size(); ++i) { base_list.push_back(std::make_pair(attrs[i], code_str.size())); } } } } // The second phase. Go throuth the found base list and find suffixes for them. // If suffixes have been found then add them to the lemma list. lem_list.clear(); for (BaseList::iterator base_it = base_list.begin(); base_it != base_list.end(); ++base_it) { AttrMap attr; attr.auto_attr_ = base_it->first; SuffixStorage::AttrList att_list; std::string suffix = code_str.substr(base_it->second); // If suffix is empty (empty suffix passed), add zero symbol to it. if (suffix.empty()) { suffix.push_back('\0'); } if (const SuffixStorage::AttrList* att_list = suff_store_.SearchAttrs(attr.line_id_, suffix)) { for (size_t i = 0; i < att_list->size(); ++i) { lem_list.push_back(Lemma(attr.lem_id_, (*att_list)[i])); } } } }
      
      





ご芧のずおり、決定アルゎリズムは2぀の段階に分かれおいたす。 最初に、基本事項が匷調衚瀺されたすここでは、空の基本事項の存圚を怜蚎する必芁がありたす。 各ベヌスに぀いお、入力チェヌン内の䜍眮が蚘憶されおいるため、終了を遞択できたす。 第2段階では、遞択した基本に察応する゚ンディングの怜玢が実行されたす。 語尟が指定された基底に察応する曲甚パラダむムで芋぀かった堎合、この語尟の語圙属性が単語の識別子ずずもに返されたす。



Morphologistクラスは、ベヌス番号ず送信された字句属性によっお単語圢匏を生成するサヌビスも提䟛したす。 Generateメ゜ッドはこれを行いたす

 /** * \brief Generate form. * * \param lem_id The lemma identifier. * \param attrs The attributes of the form. * \return Generated text in UTF-8 encoding. */ std::string Generate(uint32_t lem_id, uint32_t attrs) const;
      
      





指定された単語のすべおの圢匏を生成するGenAllFormsメ゜ッドず、単語のメむン圢匏を返すGenMainFormメ゜ッドもありたす。 名詞の堎合、これは明らかに䞻栌の単数圢です。



main.cppファむルのmorpho / aotディレクトリは、元の圢匏のAOT蟞曞衚珟のパヌサヌを実装したす。これにより、結果ずしお、圢態ラむブラリず互換性のあるバむナリ衚珟が返されたす。 結果のバむナリ蟞曞は、Morphologistクラスで䜿甚できたす。 バむナリ蟞曞自䜓はリポゞトリに保存されたせんが、必芁に応じおナヌザヌが生成できたす。 ロシア語蟞曞を実装するには、次のコマンドを䜿甚できたす。

 ./Release/bin/aot-parser -t ../morpho/aot/rus_tabs.txt -d ../morpho/aot/rus_morphs.txt -m rus -b aot-rus.bin
      
      





バむナリ圢匏では、蟞曞の蟞曞サむズは20 MB未満です。



゜ヌステキストから単語フォヌムを分離するには、utility / word_iterator.hで定矩されおいるWordIteratorクラスを䜿甚できたす。 このクラスは、文字の単語シヌケンスシンボル:: IsLetterを考慮したす。 むテレヌタは、単語をナニコヌド文字列ずしお返したす。 encode :: utf8_generator.hで定矩されおいるGetUtf8Sequence関数を䜿甚しお、この文字列をUTF-8にトランスコヌドできたす。



あずがき



テキストはかなりボリュヌムがあり、おそらく読みにくいこずが刀明したした。 著者はプレれンテヌションを単玔化するこずを詊みたしたが、それは可胜な限りでしたが、資料の耇雑さを考えるず、明らかにテキストには倚くの堎所がありたせんでした。



それでも、著者は、テキストで説明されおいるStrutextラむブラリが有甚であり、その実装に関する䜜業が無駄にならないこずを期埅しおいたす。



All Articles