Компютърен коректор на правописа за български език


Глава І – Построяване на речник



страница2/3
Дата22.02.2017
Размер372.73 Kb.
#15516
1   2   3

Глава І – Построяване на речник

За построяване на речника на българските думи е разработен отделен модул за обработка на файлове, съдържащи класифицирана информация за думите в българския език. Детайлно ще бъде разгледан процеса по обработване на файловете и получаването на изходни резултати подготвени за употреба от текстовия коректор. Входните ресурси за този модул са файлови структури, разработвани за системата BgOffice (http://bgoffice.sourceforge.net) от Радостин Раднев <radnev@yahoo.com>. Те са базирани изцяло на книгата/учебника на Кръстев Б., “Морфология на българския език в 187 типови таблици”. С., НИ, 1984. и се разпространяват свободно под GNU/GPL лиценз (General Public License).

Какво точно представлява общото право на обществено ползване GNU ?

Това право е предназначено да гарантира свободата да се обменят или променят свободните програми - както и да гарантира, че програмите са свободни за всички потребители. Това общо право на обществено ползване е в сила за повечето от програмите на Фондацията за Свободни Програми (Free Software Foundation, Inc.), както и за програми чиито автори са решили да го използват.

Настоящото общо право на обществено ползване е разработено така, че да осигури свободата да бъдат разпространявани копия на свободните програми; да се притежава изходния код или възможността да бъде получен; да е възможно да се променя програмата или да се използват части от нея в друга свободна програма; да съществува увереността, че тези действия са разрешени.

Как е разделена и класифицирана информацията ?

Информацията за всеки тип дефиниран в книгата се пази в отделен файл. Файловете започват с префикса "bg". Следва трицифрено число съответстващо на типа. Записването се извършва като водещите позиции се запълват с нули:

001, 002, ..., 010, 011, ..., 100, 101 ...

Някои типове имат подтипове. За дефиниране на подтип се използват малките латински букви: 001, 001a, 001b, 002, 003, 003а. Разширението е ".dat". Получава се следната поредица: bg001.dat, bg001a.dat, bg002.dat, bg003.dat, bg003a.dat, ...

Препоръчва се при обработка типовете да не се прескачат, за да не се изгубят цели класове от думи. Ако някой тип има подтип(ове) те следват начина на подреждане на малките латински букви. За класификация и разделение на данните се използва йерархичната структура на файловата система (директории и поддиректории).

Следва описание на структурата на директориите и типовете, дефинирани в книгата:

noun - съществителни (1 - 75)

male - мъжки род (1 - 40)

female - женски род (41 - 53)

neutral - среден род (54 - 75)

adjective - прилагателни (76-89)

pronominal - местоимения (90 - 130)

personal - лични (90 - 97)

demonstrative - показателни (98 - 105)

possessive - притежателни (106 - 113)

interrogative - въпросителни (114 - 117)

relative - относителни (118 - 120)

indefinite - неопределителни (121 - 123)

negative - отрицателни (124 - 126)

general - обобщителни (127 - 130)

numeral - числителни (131 - 141)

cardinal - бройни (131 - 139)

ordinal - редни (140 - 141)

verb - глаголи (142 - 187)

various - (188 - 198) разни, които ги няма в книгата

adverb - наречия (188)

conjunction - съюзи (189)

interjection - междуметия (190)

particle - частици (191)

preposition - предлози (192)

months - месеци (193)

names - лични и географски имена (194 +)

bg_towns - български населени места (195)

bg_various - български географски понятия (194)

capitals - списък на столиците (197)

cities - списък на световноизвестните градове (198)

countries - списък на страните (196)

various - чужди географски понятия (199)

names_and_terms - имена и запазени марки (200)

names_and_families - имена и фамилии (201 - 207)

families - фамилни имена (201 - 204)

names - лични имена (205 - 207)


Типовете след 187 не са описани в книгата. Те са обект на авторство от създателя им.

Във всяка една директория има файл description.dat, който описва типа на думите и възможните форми. Тези файлове не се използват при генерирането на речниците за проверка на правописа. От съображения за намаляване обема на речника собствените имена и фамилиите не са включени при изграждането му.

Как се извършва обработката на входните файлове.

Модулът на приложената програма DictBuilder ще наричаме още генератор на речник. В този раздел ще бъдат проследени алгоритмичните стъпки извършвани от генератора и ще се опишат правилата, дефинирани във файловите структури, които се съблюдават.

Информацията за всеки един тип се пази в отделен файл. При обработката на файла трябва да се спазват следните правила:


  1. Игнорират се всички празни редове.

  2. Игнорират се всички интервали в началото и в края на реда.

  3. Всичко след знака # се смята за коментар и не се обработва.

  4. На всеки ред може да има само по един елемент.

  5. Всеки файл има две задължителни секции Окончания и Думи и незадължителна секция Тест. Секциите трябва да завършват със знака двоеточие.

  6. Секциите Окончания и Думи трябва да присъстват само един път, докато секцията Тест може да се среща произволен брой пъти.

  7. Секцията Окончания трябва бъде първа. След това може да има нула или няколко секции Тест. Секцията Думи се намира задължително на последно място.

Секцията Думи съдържа думите, които принадлежат на този тип. В нея продължават да важат правилата за обработка на файла. Не се допуска да има празни редове, но са възможни коментари и интервали в началото и края на думата. Секцията свършва с края на файла. Т.е. след реда "Думи:" до края на файла следва списък на думите, всяка на нов ред. Възможно е да има и коментари. Записват се само основните форми на думите. Производни форми не се допускат. Не са дефинирани префикси.

Т.е. думите "разбиране" и "неразбиране" не се описват с префикси, а трябва да са налични и двете. Общият брой речникови думи които се появяват в резултат на обработката на файла е произведението на броя елементи в секцията Думи: и броя елементи в секцията Окончания: .
Секцията Тест служи за задаване на тестови случаи. В приложения речников генератор тестове не се провеждат от съображения за ефективност по бързина, при изготвянето на продуктовият файл. Тази секция е необходима за да се провери машинно коректността на производните форми.
В секцията Окончания са описани правилата за образуване на производни форми от основната форма. Тези правила са дефинирани като регулярни изрази по отношение на отделните морфеми и на тяхна основа се формират различните словоформи.

Първият елемент има специално значение за тази секция и е задължителен.

1. Този елемент съдържа окончанието, което трябва да се извади от края на основната форма. Нулата (0) означава, че няма какво да се извади (празен низ). Случва се окончанието да съвпада с основната форма на думата, като това не променя алгоритмите по обработка и не внася нови допълнителни правила.

2. Може да се специфицира допълнителен филтър (условие, на което отговарят думите в този тип), разделен със запетая (,). Ако няма зададен допълнителен филтър, като такъв се подразбира окончанието, което трябва да се извади. Ако е 0, значи няма филтър и всяка една дума може да влиза в този тип. Филтърът се задава чрез използването на регулярни изрази.

3. В случаите, когато има изменение на звук, окончанието трябва да съдържа клас от допустими символи. Може да има само един клас. Ако се налага използването на два класа, се дефинира подтип.
Останалите елементи на тази секция са окончанията, които се добавят за да се получи съответната форма. Нулата (0) отново означава, че няма какво да се добави (празен низ). Ако някоя форма не съществува, се задава знака минус (-).

Ако първият елемент съдържа клас от допустими символи на съответното място, те се задават със знака въпросителна (?).

Отново е възможно наличието на коментари в ред от секцията Окончания, така че проверките за знака # трябва да бъдат правени. При типове съдържащи малко на брой елементи, тези елементи често се цитират в основния ред на секцията.
Примерна извадка от noun/male/bg001.dat:
Окончания:

0 основна форма

0 ед.ч.

а ед.ч., непълен член

ът ед.ч., пълен член

ове мн.ч.

овете мн.ч. членувано

а бройна форма

- звателна форма
Думи:

......


болт

блок


град

....


Формират се думите
болт болт болта болтът болтове болтовете болта

блок блок блока блокът блокове блоковете блока

град град града градът градове градовете града
Извадка от noun/male/bg002.dat:
Окончания:

я[гхтрсв]

основна форма

я?

ед.ч.

е?а

ед.ч., непълен член

е?ът

ед.ч., пълен член

е?ове

мн.ч.

е?овете

мн.ч. членувано

я?а

бройна форма

-

звателна форма

Думи:


......

бряг


смях

.....
Процедурата по обработка на този клас думи е следната:


1. Запомня се последната буква от думата. Условно я наричаме окончание.

2. Запомня се и началната част от думата, достигаща до последното срещане на „я”. Този компонент се счита условно за корен.

3. Извършват се итерации по броя на регулярните изрази.
На всяка итерация въпросителният знак се заменя с окончанието и всичко това се добавя към отделения корен.

Ето и генерираните думи:

бряг брега брегът брегове бреговете бряга

смях смеха смехът смехове смеховете смяха


Пример с допълнителен филтър от noun/male/bg016.dat:

Окончания:
х, [аъиеоуяюр]х основна форма

х ед.ч

ха ед.ч непълен член

хът ед.ч пълен член

си мн.ч

сите мн.ч членувано

ха бройна форма

- звателна форма



Думи:

кожух


монарх
В този случай имаме специфициран допълнителен филтър, указващ че предпоследната буква в думата трябва да е някоя от изброените. Практически тези филтри спокойно могат да бъдат пропуснати. И те действително се игнорират в процеса на изготвяне на речника, тъй като не оказват абсолютно никакво влияние върху резултатите от генеративния процес, а единствено имат отношение към разширяването
на речниковата структура. Тъй като разширяването на стандартният речников фонд не е обект на текущата разработка, то и значението на този допълнителен филтър се игнорира.
Като завършек на примерите с файлови структури, ще бъде разгледан общия вид на един филтър и в детайли ще бъде проследен процеса по обработката и извеждането на резултати.
При стартиране на програмата речников генератор (DictBuilder.exe) се зарежда интуитивен графичен интерфейс. Не е предвидено тази програма да бъде пряко използвана от потребителите на текстовия редактор. При регулярните обновявания на базата от данни е желателно да се стартира тази процедура по изготвяне на обновен речник. Единствена функционалност на програмата-генератор е да създаде речников файл, на основата на съществуващите файлови структури и да превърне този речник във вид използваем от текстовия редактор.

При запазване на файловата подредба на предоставените сорс-кодове и изпълними модули, програмата генератор се стартира от \DictBuild\DictBuilder.exe. Така релативно се проследява пътят до BGOFFICE-4.0\DATA директорията, в която се намират ресурсните файлове. Предвидено е програмата да заработи без подаването на специални параметри от страна на потребителя – достатъчно е да бъде запазено подреждането на файловете във вида, в който са предоставени. При евентуално разместване на модулите, очакваният релативен път не може да бъде открит и затова е дадена възможност на потребителя да специфицира самостоятелно пълния път до директорията с ресурсните файлове. При потвърждаване за нововъведения пълен път, се прави проверка дали е валиден и ако е, едва тогава се стартира операцията по обхождане на файловете.

Натискането на Build бутона извиква основната програмна функция. Очаква се в текущата директория да бъде открит файлът Folders.txt, в който са описани директориите, съдържащи класовете думи, които ще се включат в речника. Този списък може да бъде модифициран за да се включат(изключат) отделни класове от думи. С демонстративна цел списъкът е така изготвен, че да се продуцира достатъчно функционален изходен файл за възможно най-кратко време.

При изпълнение на програмата се започва последователно обхождане на този списък и се формират пълните пътища до описаните директориите с ресурсни файлове. С итеративно обхождане на наличните файлове във всяка директория, се стартира стандартна функция за обработка на съответния файл.


За нагледност по проследяването, ще се разгледа извадка от файла bg057.dat
bg057.dat – съществителни от среден род

  1. # Доста рядко срещан тип. Има дефиниран подтип за някои определени

  2. # случаи, за да опростим описването. Подтипът завършва с четири

  3. # букви а не с три както този.




  1. Окончания:

  2. я[тзкл]о # основна форма

  3. я?о # ед.ч.

  4. я?ото # ед.ч. членувано

  5. е?а # мн.ч.

  6. е?ата # мн.ч. членувано




  1. Тест:

  2. тяло

  3. тяло

  4. тялото

  5. тела

  6. телата




  1. Думи:

  2. ...

  3. желязо

  4. ...




  • Файлът се отваря за четене и се ограничава достъпът за модифициране на други програми. Оставя се единствено възможност за четене, тъй като това не създава проблеми при обработката.

  • Създава се списъчна структура, в която ще се запазят дефинираните окончания – редове 5-9 включително.

  • Създава се булев флаг, който да контролира въвеждането на продуцираните словоформи в общия масив. В началото флагът има забранителен характер и ще си смени стойността едва при достигането до секция Думи.

  • Започва четенето на файла ред по ред.

    • При прочитане на нов ред, първо се прави проверка за коментар – търси се символа за коментар # и ако бъде открит, от прочетения ред се отрязва частта, следваща #.

    • Премахват се празните символи от началото и края на получения низ.

    • Ако след тези операции, низът се състои от празен символ, управлението се връща при четенето и се разглежда следващ ред.




    • При валидна стойност на прочетения ред, се изследва неговото съдържание.

      • Ако редът има стойност “Окончания:“, във вече създадената списъчна структура, циклично започват да се добавят прочетените редове, докато не се срещне нова секция – а именно Тест: или Думи:, при което добавянето в списъка с окончания се прекратява. При всеки ред-кандидат за валидно окончание, се прави проверка дали няма коментари в него, както и дали е празен символ.

      • Ако редът няма стойност Окончания: , това може да значи 4 неща

        • Коментиран ред – случаят вече е обработен

        • Празен ред – също е обработен с по-предишни проверки

        • Взет е от вътрешността на секция Тест

        • Взет е от вътрешността на секция Думи

      • Прави се проверка дали вече сме достигнали секцията Думи (ако флагът разрешаващ добавяне на думи е в позволителен режим, това значи че секцията е достигната)

        • Ако флагът е със забранителен характер – секцията думи не е достигната, следователно редът следва да се игнорира.

        • Флагът е с разрешителен характер - това значи, че прочетеният ред е дума и следва да се стартира под-процедура за намиране на производните и форми.

Управлението е достигнало до точка, след която трябва да започне образуване на производни форми. За да се образува нова форма от основната, която вече е прочетена, се стартира нова процедура по отделяне на морфемите – така наречените условен корен и заменящ символ, който ще замени променливата буква при формиране на окончанията.

Разглежда се регулярният израз, стоящ на първа позиция в секцията Окончания. В случая това е изразът я[тзкл]о. Смисълът му е следният – към този клас се причисляват думи от среден род, завършващи на о, като предпоследната буква е някоя измежду буквите т, з, к, л, а буквата преди нея задължително е я. Разглежданата дума в случая е желязо и е видно че отговаря на изискванията.


Започва обхождане отзад-напред по символите на регулярния израз. При достигане на символа затваряща скоба ” ] ”, се взима символът от думата, отстоящ на толкова позиции, колкото символи са обходени до достигане на скобата. Той трябва да бъде един, измежду затворените в скобите символи. Той се запомня като заменящ символ. Обхождането на елементите на регулярния израз продължава, като всички символи до достигане на отваряща скоба ” [ ” се игнорират.
След достигането на отварящата скоба, продължава индексирането и по символите на думата – колкото повече символи в регулярния израз бъдат прочетени, толкова по-напред се премества индексът в думата. Така при завършване на символите в регулярния израз, се е установила позиция в разглежданата дума. Тази позиция може да бъде нула или положително число, но не е възможно да продължават итерации по символите на регулярния израз, като паралелните итерации по буквите на думата да доведат индекс по-малък от нула. Символите от началото на думата до този индекс се считат за условен корен. В случая с думата желязо, това е низът жел. Обръщам отново внимание на факта, че е възможно условният корен да се окаже с нулева дължина, като това не е грешно, защото в такива случаи формираните окончания съдържат изцяло низа на разглежданата дума.

И така – след като са установени коренът и заменящият символ, управлението се връща при генерирането на формите на разглежданата дума.




  • Коренът и заменящият символ се записват в съответните променливи.

  • Започва циклично обхождане на списъка с окончанията, като във всяко окончание се заменя символът “?” със заменящия символ (ако съществува). Ако окончанието е (0), то не се добавя към корена, а ако е (-), директно се пристъпва към следващото окончание от списъка.

  • Полученото по този начин окончание се добавя към условният корен и получената форма от основната дума се добавя в общият списък с думите.

Ако секцията Думи не е достигната все още - (флагът има забранителен характер), се прави проверка дали прочетеният ред не съдържа именно стойността „Думи:” .

Ако е така – флагът променя стойността си към разрешителен характер, като следващият прочетен ред със сигурност се очаква да бъде дума.

След обработка на всички възможни файлове, се натрупва количество думи в общият списък около 1.000.000, но за целите на програмата се използват рационално около 870.000. Сред тях има известен брой повтарящи се. Такива са например думите врата - ж.р., ед.ч. и непълно членуваната форма на думата врат –м.р., ед.ч. – също врата.. Броят на такива думи в настоящия речник е около 20000 като те биват изключвани от него.

След пълното обхождане по директории и файлове и след генерирането на общото множество думи, се прави лексикографско сортиране на списъка с думи и след това повторенията се премахват. Сортиращият метод който съм използвал е бързото сортиране по Хоор. За отсяване на повторенията съм използвал стандартна практика на линейно обхождане на масива. Всеки поредно разгледан елемент бива сравняван с последният уникален елемент. Ако са еднакви, разглежданият се изключва от масива и се пристъпва към следващия. Ако пък са различни, разглежданият се обявява за «последен уникален елемент» и се пристъпва към следващият. Така с линейно обхождане на масива се прави премахване на повтарящите се елементи.

Изходният масив от думи се записва в текстов файл Dictionary.txt като на първият ред за улеснение в текстовия коректор се записва броят на всичките му елементи.

В заключение...

Тази програма съвсем точно обработва заложената логика при изготвяне на файловете със списъци от думи и гарантира коректността на изходните данни чрез коректността на използваните алгоритми. Обработваните данни като цяло са изключително много и времето за обработка може да се окаже доста дълго – в зависимост от включените класове думи и изчислителната мощност на компютъра. Все пак изходен файл се генерира веднъж на всяка актуализация на базата данни, така че продуцирането му не би трябвало да затрудни потребителя.

Залегнала е идея за бъдещото развитие при този модул и при самият текстов коректор за автоматично обновяване на базата данни. Така при стартиране на текстовия редактор ще се прави проверка през интернет за наличието на по-актуална база, и ако има такава тя да бъде изтеглена за секунди и заредена. В момента, за улеснение на потребителя е направено проследяване на текущата задача по изготвянето на речника.

Текстов редактор с вграден коректор на правописа за български език

За построяване на текстовия редактор съм използвал възможностите, предоставени от библиотеката с класове MFC (Microsoft Foundation Classes). Програмният модел, на който съм се спрял, е мулти-документно приложение.

В изготвената рамка участват така наречените изгледи (View) и документи. Всеки такъв изглед манипулира документи от дефиниран тип. За целите на тази програма съм създал специален компонент, който репрезентира единичен документ и самостоятелно се грижи за управлението на данните. Този клас е модификация на текстово поле (CEdit), като множеството методи на стандартния компонент са предефинирани така, че да изпълняват специфична функционалност, обслужваща определени под-задачи.

Разработени са и съответни методи, осигуряващи реализирането на крайната цел, а именно построяване на коректор за правописа на българския език.

Текстовият редактор с коригиращи функции изпълнява задачи от следното естество:


  • отразява точно действията на потребителя по отношение въвеждането на входни данни

  • проследява своевременно написания текст, като проверява правописа на отделните думи

  • дава визуални знаци за присъствието на сгрешени и непознати думи в речниковия фонд

  • проверява наличието на специфични словосъчетания с участието на съюзите „с”, “със”, “в”,”във”, като проверява коректността на изписването на тези конструкции

  • при желание от страна на потребителя предоставя списък от думи близки до начина на изписване на дадена сгрешена (непозната) дума.

  • в случай на неправилно построена конструкция с участието на изброените съюзи, се дават визуални знаци ( подчертаване с червена линия ), за направената грешка – както за основната дума, така и за съчетанието от двете думи.

  • при поискване подава списък от конструкции, близки до сгрешената, като при това предоставената конструкция е граматически правилно построена.

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

  • Разполага с една от най-богатите речникови бази данни за български език, като същевременно се справя с лекота при търсенето сред огромното количество данни

  • осигурява възможност за обогатяване и допълнение на речниковия си фонд със специфични термини и думи, незаложени в стандартния речник .

  • извършва бързо търсене по наличните базови данни.

  • извършва проверките за коректност само във видимата област на монитора като не изразходва изчислителна мощност за участъци от текста които текущо не се показват на екрана.



Зареждане и съхранение на данните


Данните се съхраняват в оперативната памет на компютъра с цел достъпа до тях да се извършва ускорено. Ето какво именно се разбира под данни в случая - това са думите от :

- речниковия файл, генериран с програмата DictBuilder, които са записани във файла Dictionary.txt

- думите дефинирани от потребителя, намиращи се във файла Custom.txt



- съчетания от двойки думи - сгрешеното изписване и правилното изписване намиращи се във файла Misspellings.txt. Тази категория думи ще бъде подробно разгледана в последствие.

Думите от всички речникови файлове са сортирани лексикографски, за да е възможно да се направи двоично търсене сред елементите. Така при наличното количество от около 870000 думи, в разстояние на максимум 20 проверки се извежда резултат дали даден текстов низ е речникова дума, или не.

В процеса на създаване на настоящия речник, бе направено отчитане на максималната дължина на наличните думи. Оказа се, че най-дългата стандартна речникова дума е с дължина 25 символа. Това число е използвано и за граница на заделеното количество байтове за всяка дума.

От една страна, това е неудобство, понеже програмата се лишава от възможността да оперира с думи по-дълги от 25 символа. Нека обаче да обърнем внимание какво се печели, за сметка на това ограничение.

Ако се използват текстови буфери, за да бъде програмата в състояние да индексира дума с произволна дължина, това значи да създадем клас, представящ текстовия низ, който си има конструктор, копиращ конструктор и вероятно методи за пресмятане на дължината. Цялата тази организация би довела до многобройни извиквания на конструктори и копиращи конструкции, при което ефективността на програмата рязко ще спадне. При модела, използван от мен, се създава един масив от структури, при които всяка структура има единствен елемент – свой масив от тип char с фиксирана дължина. Така достъпът до елементите е директен и не се загубва процесорно време за копиране на низове.

Количеството налични данни е сравнително голямо по обем – пълната версия на речника съдържа над един милион записа. Ако трябва да се създадат един милион обекта за тях, това ще отнеме около 400 мегабайта от оперативната памет на компютъра и е възможно да доведе до известно неудобство за потребителя по отношение на общата производителност на компютърната му система. Експериментално бе проверено, че при 250000 думи, записани в обекти от тип CString, изразходваната памет бе между 90 и 100 мегабайта.

Зареждането на такова количество данни, дори при най бързите компютри отнема известно време и заради това прочитането им се извършва паралелно на работата на самата програма. При инициализацията на главния клас се стартира паралелно изпълнение (нишка), където става четенето на файлове и попълването на масивите. Сега става ясно защо всъщност на първия ред на речниковия файл, се описва броя на думите съдържащи се в него – това число е нужно, за да се оразмери масивът за съхранение на данните. Доста по-удобно е това число да се пресметне на пред-процесорно ниво - по време на генериране на речника - отколкото по време на работа на програмата, да се обхожда файл от стотици хиляди редове, за да се види техният брой.

Чрез използването на паралелно изпълнение (нишка), главната програма остава в режим на обработка на събитията от потребителя, без да се получава нежеланият ефект на „замръзване” на процеса .


От вторият файл – custom.txt, който съдържа думите, дефинирани от потребителя, се запълва отделен масив, понеже вмъкването им в подредения масив от стандартни думи ще бъде свързано с неговото пренареждане, а това е тежка и ненужна операция. Думите в потребителският речник също са лексикографски сортирани. В общият случай тези думи са малко на брой и вмъкването на нови думи става именно там, а не в стандартния речник, защото потребителският като по-малък , се сортира и преиндексира по-лесно.
Кога се прави проверка на текста
При обичайната си работа с компютърната система, потребителят нормално генерира събития - натискане на клавиш, затваряне на прозорец, преместване на прозорец и т.н. Следните 3 събития: натискане на клавиш, скролиране на прозореца, и промяна на размерите му би могло да доведе до промяна в съдържанието на видимия текст в редактора. Затова при такива събития се налага да се провери текста за коректност. За да се избегнат ненужните проверки на думи, които текущо не се виждат на монитора, проверките се стартират от първият видим ред на текстовото поле и завършват при реда, чиито координати не надвишават координатите на клиентската област на текстовото поле. Не всяко натискане на клавиш, обаче стартира проверка на текста – ако отпечатания символ не е разделител, то се счита, че не е необходима моменталната проверка на видимия текст. Но при отпечатване на разделител задължително стартираме проверка за да отразим нововъведената дума. Списъкът от разделители е следният: .,!?+-=[]_():;'\"#$%^&*~ - това са специалните знаци от стандартната кодова таблица, в това число и символът „интервал” (ASCII 32).

Проверките се правят ред по ред, като думите от всеки ред се обособяват и итеративно се стартира търсене. Отделянето на думите една от друга става посредством обхождане на символите от реда един по един и там където има знаци-разделители се обособяват думи. Думите не се изпращат веднага след отделянето им на проверяващият модул, а се записват в един списък за да могат да бъдат анализирани. Този анализ се прави специално за да бъдат намерени конструкциите със съюзите "с","със","в" и "във".

След отделянето на всички думи в списък започва последователното им подаване на търсещата функция.
Търсене сред наличната база от данни
При фонд от 870000 сортирани думи в стандартният речник, един от видовете търсене, който дава резултати за смислено добро време е двоичното търсене. При този размер на масива, връщането на резултат става в порядъка на 20 лексикографски проверки, което е задоволително добро като сложност и като време за изпълнение.

Потребителският речник също е сортиран и търсенето в него се извършва по същия начин със същия алгоритмичен похват

Характерният за тази програма речник на поправените думи се представя като списък от 3-компонентни структури. Единият компонент е ключът за търсене (сгрешената дума), втория компонент е речниковата дума, с която е поправена, а трети компонент е броят на тези поправки. Търсенето и тук е двоично за да се постигнат най-добри резултати.

Последното место където се търси дадена дума е в списъка с игнорираните думи. Този списък не се съхранява върху твърдия диск, а се създава от потребителя по време на работата му с текстовия редактор и се освобождава при затваряне на документа.

Игнорираните думи са такива, които не фигурират в никой от речниците и потребителят не желае нито да бъдат маркирани като грешни, нито да ги включи в потребителският си речник.
Редът на претърсване на речниците е следният:

0) Най напред се проверява дали думата не е част от сложна конструкция.

1) Ако не е в съчетание с никой от посочените 4 съюза, първо се претърсва речника с игнорираните думи, тъй като се очаква там да има най-малко елементи от всичките, и по този начин биха се спестили известно количество проверки ако търсенето даде положителен резултат още тук..

2) На второ място се проверява потребителския речник, защото там се очаква да има по-малко думи от стандартния.

3) След това се прави търсене и в стандартния речник.

4) Ако и там търсенето е безуспешно, се проверява дали думата не е от множеството на поправяните думи. В случай на тотално несъответствие, думата (словосъчетанието) се маркира с червена линия.


Представяне на грешките като обектен модел

С маркирането на дадена дума задълженията на коректора към нея не свършват. Създава се обект който съхранява нейните координати спрямо клиентската област и се записва в списък. Една маркирана дума има следните характеристики:



  1. Целочислен индекс на началният й символ отмерен от началото на текста в текстовото поле

  2. Правоъгълник чиито координати са координатите на думата спрямо текстовото поле

  3. Стойността на самата дума

Така в последствие, когато потребителя натисне десния бутон на мишката в полето за писане се проверява дали координатите на курсора не попадат в някоя от областите запомнени като проблемни. В случай, че курсорът е бил върху маркирана дума се взима стойността й и се задвижва механизъм за търсене на евентуални заменящи думи.


Заменящи думи – начини на формиране

Ако потребителят не желае да поправи самостоятелно дадена сгрешена дума, той може да прехвърли тази задача върху редактора. Натискайки десен бутон на мишката върху маркираната област се стартира процедурата по търсене на заменящите думи. За решаването на тази задача съм разработил четири методологии които работят изключително добре и дават очакваните резултати.



  • Проверка за заменена буква – итеративно се обхождат символите на думата и се прави замяна на всеки неин символ с другите символи от азбуката. Сложността на този алгоритъм е С*N*(O(търсене)) – тук константата С е точно 30, колкото са буквите в българската азбука, N e дължината на думата, О(търсене) = Log2(MAX_WORDS)

  • Проверка за разместени съседни букви – отново се прави обхождане на думата по дължината и, като всеки две съседни букви се разместват и така полученият низ се търси в речника – сложността тук е далеч по-малка от предходния случай: броят на такива размени е N-1, където N е дължината на думата.

  • Проверка за изпусната буква – итеративно по дължината на думата се прави вмъкване на всеки възможен символ от азбуката на последователно на позиции от нулева до N+1 (ако се номерират да започват от 1). Извършваните проверки в този случай са най-многобройни, тъй като линейният коефициент е N+1.

  • Проверка за излишно добавена буква – сравнително прост случай – последователно се изключва всеки от символите на думата и се проверява дали така получената дума е речникова.

Някои от методите могат да продуцират едни и същи валидни думи. Например при написания низ КОЛАА, методът по изключване на символи един път ще изключи четвъртата буква и ще открие валидната дума КОЛА. На следващата итерация ще изключи петата буква и отново ще открие думата КОЛА. Очевидно не е нужно списъкът от предложения за замяна да съдържа еднакви думи, затова преди всяко включване в него се прави проверка дали валидната дума вече не фигурира вътре. Реално, всеки от четирите метода могат да генерират повторения, затова се правят проверки за включване при всеки от тях.


Взаимодействие на потребителя със системата в случаи с маркиране на грешки
Ако никой от четирите метода за откриване на думи не даде резултати, се създава меню с 2 възможности – добавяне на думата в потребителския речник – ако потребителят е сигурен за нейния правопис, и игнориране на думата за да не се подчертава повече като грешна.

В случаите пък когато бъдат открити думи близки по изписване със сгрешената първите 15 от тях се подреждат в контекстно меню и то се визуализира. Избирането на коя да е дума от менюто заменя маркираната област. За да бъде възможно избирането на елемент от контекстно меню да извиква точно определена функция, е нужно да се дефинират идентификатори за елементите в менюто, към които се прикачат думите от списъка. Картата на съобщенията се грижи да установи кой е идентификатора генерирал събитието “избор от контекстно меню” и по този начин се предава управлението към функцията която ще замени сгрешената дума с нейна правилна форма. Именно тази технология налага фиксирането на краен брой думи получаващи възможност за поместване в контекстното меню. Така че изборът на числото 15 в случая е субективно, като е въпрос на проучване да бъде променено към стойност удовлетворяваща нуждите на потребителя в по-голяма степен.


Особени конструкции - словосъчетания на съюзите "с" , "със", "в","във"
Както е известно - в българския език има правила за изписване на тези 4 думи, когато са в съседство думи с които ги следват. В представеният текстов редактор се провежда анализиране на думите и при срещане на някой от тези съюзи се създава обект - сложна конструкция от съюза и последващата го дума. За тези конструкции важат особени правила при проверка на коректността им.

Съществуват 2 варианта за изписване на грешна конструкция

- основната дума е в коректна форма, но съюзът отпред не е правилно поставен

- основната дума е сгрешена(непозната) – тук няма значение дали съюза е правилно поставен, щом думата е грешна.

Не се разглежда случай със сгрешен съюз, тъй като неговата коректност е основа за оформяне на сложна конструкция. Ако съюзът отпред е неправилно изписан, това е стандартен обект подлежащ на проверка и редакция.

Функция-валидатор на конструкции връща стойности “да” или “не” при входен елемент конструкция. Тя отчита съвместимостта на използваният съюз и думата. Например, типовете изрази “във гората”, “в водата”, ”със книга” , ”с захар” ще върнат винаги отрицателен резултат.

Първи случай - основната дума е в коректна форма. Следва да се промени използваният съюз. Щом конструкцията е цялостно грешна, това значи че именно съюзът е използван неправилно и без много специални проверки се заменя с обратната си форма - "със" заменя "с" и обратно, "в" заменя "във" и обратно.

Втори случай - основната дума е сгрешена (непозната).

Прави се търсене, за да се открият думи, близки до основната и се съблюдават правилата за изписване на съюза, предхождащ думи започващи с буквите "с","з","в","ф".Така се предлагат цялостно сглобени конструкции, които заменят неправилно изписаната.

Например, при конструкцията “с сова”, валидаторът отчита несъвместимост. Думата “сова” е в коректна форма, следователно ще бъде направено единствено предложение за замяна “със сова”. В случая с неправилната основна дума “в фония”, ще бъде формиран списъка: “в ония”, “във фуния” и т.н.

При избор на опцията ADD от контекстното меню се прави отделяне на основната дума от съюза и самостоятелно се добавя в потребителския речник. При избиране на менюто IGNORE цялата конструкция се записва в списъка на игнорираните думи, като не се разделя на основна част и на съюз.

... в заключение ...


След всичко написано дотук, ще обобщя с няколко изречения характеристиките на програмата BgSpellChecker – текстов редактор с вграден коректор на правописа за българския език.

Представената програма е напълно функционално приложение за обработка на текстови файлове, което успешно се справя с проверки на правописа за текстове на български език. В него са реализирани всички стандартни операции за работа с текстове. Поддържа възможност за управление на множество файлове, като базата от думи за всички тях е обща. За всеки отворен файл се подържат локални данни валидни само за него. Функциите за коригиране на текста работят по удобен и интуитивен за потребителя начин.

Използваните алгоритми са подбрани и оптимизирани така, че да дават най добри резултати. Алгоритмите за обследване на близки по изписване думи, в повечето случаи дават най пълни резултати сред аналогичните продукти от подобно естество. По отношение на изразходваните системни ресурси тази програма не представлява затруднение за съвременните операционни системи. Не изразходва излишна изчислителна мощност извън необходимата. Предлага възможност за разширяване на базата си, като това разширяване може да бъде направено и от външни приложения. Анализира действията на потребителя и автоматично обработва определена група от допуснати грешки. Значително нововъведение е синтактичната проверка за правилно изписани словосъчетания с участието на групата съюзи “с”,”със”,”в” и ”във” и предлагането на граматически правилни заместващи конструкции. Може да бъде използвана успешно и като коректор за други езици, като достатъчно условие е да разполага със съответния речник в установения формат.

В следващите версии ще бъде въведена автоматична актуализация на базата от данни и поддръжка на различни файлови формати. Програмата ще се дистрибутира с отворен код, като се даде възможност на потребителите да я модифицират според нуждите и възможностите си.




Сподели с приятели:
1   2   3




©obuch.info 2024
отнасят до администрацията

    Начална страница