Source code for pyknp.juman.mlist

# -*- encoding: utf-8 -*-

from __future__ import absolute_import
from __future__ import unicode_literals
from .morpheme import Morpheme, JUMAN_FORMAT
import unittest


[docs]class MList(object): """ ある文に関する形態素列を保持するオブジェクト. """
[docs] def __init__(self, spec="", juman_format=JUMAN_FORMAT.DEFAULT): self._mrph = [] self._readonly = False self.comment = "" mid = 1 if spec != "": for line in spec.split("\n"): if line.strip() == "": continue elif line.startswith('#'): self.comment += line elif line.startswith('@') and not line.startswith('@ @'): self._mrph[-1].push_doukei(Morpheme(line[2:], mid, juman_format)) mid += 1 else: mrph = Morpheme(line, mid, juman_format) if juman_format == JUMAN_FORMAT.LATTICE_TOP_ONE: if 1 not in mrph.ranks: continue elif self._mrph and self._mrph[-1].mrph_id == mrph.mrph_id: self._mrph[-1].push_doukei(mrph) continue self.push_mrph(mrph) mid += 1
[docs] def push_mrph(self, mrph): if self._readonly: return self._mrph.append(mrph)
[docs] def set_readonly(self): self._readonly = True
[docs] def spec(self): """ 形態素列の全文字列を返す.Juman による出力と同じ形式の結果が得られる. """ spec = "" for mrph in self._mrph: spec = "%s%s" % (spec, mrph.spec()) for doukei in mrph.doukei: spec = "%s@ %s" % (spec, doukei.spec()) return spec
[docs] def new_spec(self): prev_mids = [0] length = 0 out = [] for mrph in self._mrph: ms = [mrph] + mrph.doukei tmp_prev_mids = [] for m in ms: out.append(m.new_spec(prev_mids, length)) tmp_prev_mids.append(m.mrph_id) length += len(mrph.midasi) prev_mids = tmp_prev_mids return "".join(out)
[docs] def mrph_list(self): """ 保持する全ての形態素のリストを返す. Returns: list of Morpheme: 形態素オブジェクトMorphemeのリスト """ return self._mrph
def __getitem__(self, index): return self._mrph[index] def __len__(self): return len(self._mrph) def __repr__(self): return 'MList(%s)' % repr(self.spec())
class MListTest(unittest.TestCase): def setUp(self): self.spec1 = """構文 こうぶん 構文 名詞 6 普通名詞 1 * 0 * 0 "代表表記:構文/こうぶん カテゴリ:抽象物"\n""" self.spec2 = """解析 かいせき 解析 名詞 6 サ変名詞 2 * 0 * 0 "代表表記:解析/かいせき カテゴリ:抽象物 ドメイン:教育・学習;科学・技術"\n""" self.mlist = MList(self.spec1+self.spec2) def test_mrph(self): self.assertEqual(len(self.mlist), 2) self.assertEqual(self.mlist[0].midasi, '構文') self.assertEqual(self.mlist[-1].midasi, '解析') def test_mrph_list(self): self.assertEqual(''.join([x.midasi for x in self.mlist]), '構文解析') self.assertEqual(self.mlist.spec(), self.spec1 + self.spec2) new_spec = """-\t1\t0\t0\t1\t構文\t構文/こうぶん\tこうぶん\t構文\t名詞\t6\t普通名詞\t1\t*\t0\t*\t0\tカテゴリ:抽象物\n""" + \ """-\t2\t1\t2\t3\t解析\t解析/かいせき\tかいせき\t解析\t名詞\t6\tサ変名詞\t2\t*\t0\t*\t0\tカテゴリ:抽象物|ドメイン:教育・学習;科学・技術\n""" self.assertEqual(self.mlist.new_spec(), new_spec) def test_doukei(self): spec = """母 はは 母 名詞 6 普通名詞 1 * 0 * 0 "代表表記:母/はは 漢字読み:訓 カテゴリ:人 ドメイン:家庭・暮らし" @ 母 ぼ 母 名詞 6 普通名詞 1 * 0 * 0 "代表表記:母/ぼ 漢字読み:音 カテゴリ:人" です です だ 判定詞 4 * 0 判定詞 25 デス列基本形 27 NIL """ new_spec = """-\t1\t0\t0\t0\t\t母/はは\tはは\t\t名詞\t6\t普通名詞\t1\t*\t0\t*\t0\t漢字読み:訓|カテゴリ:人|ドメイン:家庭・暮らし -\t2\t0\t0\t0\t\t母/ぼ\t\t\t名詞\t6\t普通名詞\t1\t*\t0\t*\t0\t漢字読み:音|カテゴリ:人 -\t3\t1;2\t1\t2\tです\tだ/だ\tです\t\t判定詞\t4\t*\t0\t判定詞\t25\tデス列基本形\t27\t """ mlist = MList(spec) self.assertEqual(mlist.spec(), spec) self.assertEqual(mlist.new_spec(), new_spec) def test_repr(self): import pyknp spec = """母 はは 母 名詞 6 普通名詞 1 * 0 * 0 "代表表記:母/はは 漢字読み:訓 カテゴリ:人 ドメイン:家庭・暮らし" @ 母 ぼ 母 名詞 6 普通名詞 1 * 0 * 0 "代表表記:母/ぼ 漢字読み:音 カテゴリ:人" です です だ 判定詞 4 * 0 判定詞 25 デス列基本形 27 NIL """ mlist = MList(spec) repr_mlist = eval(repr(mlist)) self.assertEqual(repr_mlist.spec(), mlist.spec()) if __name__ == '__main__': unittest.main()