yandex / tomita-parser

Other
495 stars 112 forks source link

Выборы фактов влияют друг на друга #124

Closed 515 closed 3 years ago

515 commented 3 years ago

Исходник: при сотрудниках Мамыкиной А. В. , Поликарповой Е. Н.,

Вариант1: При этом варианте выбирает отлично только первую фамилию и должность

Person -> PersonStatus interp (Person.PersonStatus) PersonName interp (Person.Name); 

Вариант2: При этом варианте выбирает отлично только вторую фамилию и должность

twoArg -> PersonName Comma;
Person -> PersonStatus interp (Person.PersonStatus) twoArg PersonName interp (Person.Name); 

Вариант3: В таком варианте выбирает фамилии нормально, но должность выбирает только для первой фамилии

twoArg -> PersonName Comma;
Person -> PersonStatus interp (Person.PersonStatus) twoArg PersonName interp (Person.Name); 
Person -> PersonStatus interp (Person.PersonStatus) PersonName interp (Person.Name);

Вопрос - чем обусловлено такое поведение, что при выборе 2-х фактов выбор работает неверно и как мне выбрать 2 фамилии с должностями?

victorbocharov commented 3 years ago

Приложите, пожалуйста, полную грамматику со всеми правилами, которые нужны для воспроизведения этой проблемы.

515 commented 3 years ago
#encoding "utf-8"
PersonStatusLight -> 'директор' | 'управляющий' | 'авминистратор';
PersonStatusLight1 -> 'продавец' | 'кладовщик' | 'охранник' | 'кассир';
Helper -> Word<kwtype=helper>; //Здесь подтягивается слово "заместитель"
PersonStatus2 -> PersonStatusLight1;
PersonStatus0 -> (Helper) PersonStatusLight;
PersonStatus1 -> PersonStatus0 interp (Person.PersonStatus) AnyWord AnyWord "г." AnyWord;
PersonStatus -> PersonStatusLight;
PersonName -> Word<kwtype="имя">;
twoArg -> PersonName Comma;
Person -> PersonStatus interp (Person.PersonStatus) PersonName interp (Person.Name);
Person -> PersonStatus1 PersonName interp (Person.Name); 
Person -> PersonStatus2 interp (Person.PersonStatus) twoArg PersonName interp (Person.Name); 
Person -> PersonStatus2 interp (Person.PersonStatus) PersonName interp (Person.Name); 

Иногда бывает написано продавцы Васильева Н.А, Грироян С.Е Нужно достать так Продавец: Васильева Н.А Продавец: Грироян С.Е

victorbocharov commented 3 years ago
#encoding "utf-8"
PersonStatusLight -> 'директор' | 'управляющий' | 'авминистратор';
PersonStatusLight1 -> 'продавец' | 'кладовщик' | 'охранник' | 'кассир';
Helper -> Word<kwtype=helper>; //Здесь подтягивается слово "заместитель"
PersonStatus2 -> PersonStatusLight1;
PersonStatus0 -> (Helper) PersonStatusLight;
PersonStatus1 -> PersonStatus0 interp (Person.Status) AnyWord AnyWord "г." AnyWord;
PersonStatus -> PersonStatusLight;

PersonName -> Word<kwtype="имя"> ( Word<wff="^.$"> );

PersonEnumInit_ -> PersonStatus | PersonStatus1 | PersonStatus2;
PersonEnumInit -> PersonEnumInit_ interp(Person.Status);
PersonEnumItem -> PersonName interp(Person.Name);

PersonEnumEnd -> "и" PersonEnumItem;
PersonEnumItems_ -> PersonEnumItem;
PersonEnumItems_ -> PersonEnumItem Comma PersonEnumItems_;
PersonEnumItems -> PersonEnumItems_ ( PersonEnumEnd );
PersonEnum -> PersonEnumInit PersonEnumItems;

на выходе:

продавцы Васильева Н. А , Грироян С. Е 
    Person
    {
        Name = Васильев Н. А
        Status = продавец
    }
    Person
    {
        Name = Грироян С. Е
        Status = продавец
    }
продавцы Васильева Н. А , Грироян С. Е , Иванов З. Ж. , Капустин К. Д. и Фёдоров К. Ц. 
    Person
    {
        Name = Васильев Н. А
        Status = продавец
    }
    Person
    {
        Name = Грироян С. Е
        Status = продавец
    }
    Person
    {
        Name = Иванов З. Ж.
        Status = продавец
    }
    Person
    {
        Name = Капустин К. Д.
        Status = продавец
    }
    Person
    {
        Name = Фёдоров К. Ц.
        Status = продавец
    }

Похоже?

515 commented 3 years ago

У вас небольшая опечатка не Person.Status, а Person.PersonStatus и еще один момент здесь PersonStatus1 -> PersonStatus0 interp (Person.PersonStatus) AnyWord AnyWord "г." AnyWord; стояло так, потому что мне название города в PersonStatus не нужно было. Я Вам очень благодарен - шас разберусь и пересмотрю что и почему я делал неверно. Спасибо огромнейшее!

victorbocharov commented 3 years ago

ну вот так тогда:

#encoding "utf-8"
PersonStatusLight -> 'директор' | 'управляющий' | 'авминистратор';
PersonStatusLight1 -> 'продавец' | 'кладовщик' | 'охранник' | 'кассир';
Helper -> Word<kwtype=helper>; //Здесь подтягивается слово "заместитель"
PersonStatus2 -> PersonStatusLight1;
PersonStatus0 -> (Helper) PersonStatusLight;
PersonStatus -> PersonStatusLight;

PersonName -> Word<kwtype="имя"> ( Word<wff="^.$"> );

PersonEnumInit_ -> PersonStatus | PersonStatus2;
PersonEnumInit -> PersonEnumInit_ interp(Person.Status);
PersonEnumInit -> PersonStatus0 interp (Person.Status) AnyWord AnyWord "г." AnyWord;
PersonEnumItem -> PersonName interp(Person.Name);

PersonEnumEnd -> "и" PersonEnumItem;
PersonEnumItems_ -> PersonEnumItem;
PersonEnumItems_ -> PersonEnumItem Comma PersonEnumItems_;
PersonEnumItems -> PersonEnumItems_ ( PersonEnumEnd );
PersonEnum -> PersonEnumInit PersonEnumItems;

Общая идея в том, что ваши правила должны отражать иерархичность структуры предложения. Для этого используйте рекурсию там, где она уместна, и старайтесь делать правую часть короче (1-3 элемента).