yandex / tomita-parser

Other
495 stars 113 forks source link

Не работают кавычки и точка #132

Closed 515 closed 4 years ago

515 commented 4 years ago

В руководстве заявлено: Punct | Точка QuoteDbl | Двойные кавычки

Исходные тексты: ... в пункте "а" разъясняется, что ... ... в пункте «А» говорится, что ...

Пробуем

par -> Word<wff="[А-Я]">;
Punkt -> Word<kwtype=punkt>; //достаем слово "пункт" из словаря
NumberPu -> Punkt QuoteDbl par interp (Article.Punkt) QuoteDbl;

Не работает, но если заменить QuoteDbl скажем на AnyWord - работает.

Исходный текст: ... пункт ном.12, место ... ... пункт ном 12, место ...

Пробуем part -> Word; vid -> part interp (City.name); cityVid -> 'ном' (Punct) vid;

Срабатывает только, когда нет точки, или если заменить Punct скажем на AnyWord - срабатывает. (конструкция не совсем верная, но чтобы понять, что Punct не работает достаточно думаю)

Теперь вопрос - как тогда ставить кавычки и точку?

Quot1 -> AnyWord<wff="«">; 
Quot2 -> AnyWord<wff="»">;
Poi -> AnyWord<wff=".">;

Такая конструкция почему-то тоже не срабатывает, а добавлять кучу всего так -

TAbbreviation "г."
{ 
key = { "abbreviation_г." type = CUSTOM } 
text = "г." 
type = NewerEOS
}

И потом городить тоже как-то не совсем верно.

Так же l-quoted и r-quoted не хотят работать(

515 commented 4 years ago

Punct - оказывается срабатывает на запятую, как и Comma

victorbocharov commented 4 years ago

Кавычки не отделяются токенизатором от слова, с которым они стоят контактно. Т.е. в приведённых примерах нет токенов, которые бы соответствовали терминалу QuoteDbl. По этой причине не срабатывает правило, с QuoteDbl. Для того, чтобы правило срабатывало только на заковыченных словах, предназначены пометы l-quoted и r-quoted. Вот так работает:

par -> Word<wff="[А-Яа-я]">;
Punkt -> "пункт";
NumberPu -> Punkt par<l-quoted, r-quoted> interp (Fact.F1) ;

Кавычки станут отдельными токенами, если их отделить от слова пробелом. Тогда будет нужен терминал QuoteDbl.

Вот так будет срабатывать в обоих случаях:

par -> Word<wff="[А-Яа-я]">;
Punkt -> "пункт";
NumberPu -> Punkt par<l-quoted, r-quoted> interp (Fact.F1) ;
NumberPu -> Punkt QuoteDbl par QuoteDbl interp (Fact.F1) ;

Как определить, что сделал с текстом токенизатор? Посмотрите в pretty output: там токены текст такой, каким его видит парсер после токенизации.

Терминал QuoteDbl, похоже, не обрабатывает кавычки-ёлочки («»). Это баг.

victorbocharov commented 4 years ago

В примере ... пункт ном.12, место ... токенизатор сделал вот так:

<span title="ном.12 ">ном.12</span>

Поэтому не срабатывает. Выхода два: либо делать препроцессинг перед томитой, либо ловить такие токены регуляркой.

victorbocharov commented 4 years ago

Если сделать вот так:

par -> Word<wff="[А-Яа-я]">;
Punkt -> "пункт";
Quot1 -> AnyWord<wff="«">;
Quot2 -> AnyWord<wff="»">;
NumberPu -> Punkt par<l-quoted, r-quoted> interp (Fact.F1) ;
NumberPu -> Punkt QuoteDbl par interp (Fact.F1) QuoteDbl;
NumberPu -> Punkt Quot1 par interp (Fact.F1) Quot2;

то правила, задающие Quot1 и Quot2, срабатывают как и ожидается:

. . . в пункте "а" разъясняется , что . . . 
    Fact
    {
        F1 = "а"
    }
. . . в пункте "А" говорится , что . . . 
    Fact
    {
        F1 = "А"
    }
. . . в пункте " а " разъясняется , что . . . 
    Fact
    {
        F1 = а
    }
. . . в пункте « А » говорится , что . . . 
    Fact
    {
        F1 = А
    }
victorbocharov commented 4 years ago

Punct - оказывается срабатывает на запятую, как и Comma

Punct, действительно, срабатывает на любую пунктуацию (в документации ошибка). Чтобы поймать именно точку, делайте вот так:

Dot -> AnyWord<wff="\\.">;