Прича о једном малом пројекту дугом дванаест година (о БИРМА.НЕТ-у по први пут и искрено из прве руке)

Рођење овог пројекта може се сматрати малом идејом која ми је пала негде крајем 2007. године, којој је било суђено да добије свој коначан облик тек 12 година касније (у овом тренутку – наравно, иако је садашња имплементација, према за аутора, веома задовољавајуће) .

Све је почело када сам, у обављању својих тадашњих службених дужности у библиотеци, скренуо пажњу да се процес уноса података из скенираног текста садржаја књижних (и музичких) публикација у постојећу базу података, не може вршити. по свему судећи, може значајно да се упрости и аутоматизује, користећи својство уредности и поновљивости свих података потребних за унос, као што су име аутора чланка (ако је реч о збирци чланака), наслов чланак (или поднаслов приказан у садржају) и број странице тренутне ставке садржаја. У почетку сам био практично убеђен да се на Интернету лако може наћи систем погодан за обављање овог задатка. Када је било изненађење што нисам могао да пронађем такав пројекат, одлучио сам да покушам да га спроведем сам.

После прилично кратког времена прорадио је први прототип, који сам одмах почео да користим у својим свакодневним активностима, истовремено исправљајући га на свим примерима који су ми дошли под руку. Срећом, на свом уобичајеном радном месту, где никако нисам био програмер, тада сам се ипак извукао са видљивим „застојима“ у раду, током којих сам интензивно отклањао грешке у својој замисли – што је готово незамислива ствар у садашњим реалностима, што подразумева дневни извештаји о обављеном послу у току дана. Процес полирања програма трајао је укупно не мање од годину дана, али чак и након тога резултат се тешко може назвати потпуно успешним – у почетку је постављено превише различитих концепата који нису били сасвим јасни за имплементацију: опциони елементи који могу бити прескочен; преглед елемената унапред (у циљу замене претходних елемената у резултате претраге); чак и наш сопствени покушај да имплементирамо нешто попут регуларних израза (који има јединствену синтаксу). Морам рећи да сам пре тога донекле одустао од програмирања (око 8 година, ако не и више), па је нова прилика да своје вештине применим на занимљив и неопходан задатак у потпуности заокупила моју пажњу. Није изненађујуће што је резултирајући изворни код – у недостатку било каквог јасног приступа његовом дизајну с моје стране – врло брзо постао незамислива мешавина различитих делова у језику Ц са неким елементима Ц++ и аспектима визуелног програмирања (у почетку је одлучено је да се користи такав систем дизајна као што је Борланд Ц++ Буилдер - „скоро Делпхи, али у Ц“). Међутим, све је то на крају уродило плодом у аутоматизацији свакодневних активности наше библиотеке.

Истовремено, одлучио сам, за сваки случај, да похађам курсеве за обуку професионалних програмера софтвера. Не знам да ли је тамо заиста могуће научити „бити програмер“ од нуле, али узимајући у обзир вештине које сам тада већ имао, могао сам донекле да савладам технологије које су тада биле релевантније, нпр. као Ц#, Висуал Студио за развој под .НЕТ, као и неке технологије везане за Јава, ХТМЛ и СКЛ. Целокупна обука је трајала укупно две године и послужила је као полазна тачка за још један мој пројекат, који се на крају протегао на неколико година – али ово је тема за посебну публикацију. Овде би само било умесно напоменути да сам покушао да прилагодим развој који сам већ имао на описаном пројекту како бих направио пуноправну прозорску апликацију у Ц# и ВинФормс која имплементира неопходну функционалност и користио је као основу за предстојећи дипломски пројекат.
Временом је ова идеја почела да ми се чини вредном да се изнесе на оваквим годишњим конференцијама уз учешће представника разних библиотека као што су „ЛИБКОМ“ и „КРИМ“. Идеја, да, али не и моја имплементација у то време. Тада сам се такође надао да ће га неко преписати користећи компетентније приступе. На овај или онај начин, до 2013. године одлучио сам да напишем извештај о свом прелиминарном раду и пошаљем га Организационом одбору конференције са молбом за грант за учешће на конференцији. На моје донекле изненађење, моја пријава је одобрена, и почео сам да правим нека побољшања у пројекту како бих га припремио за презентацију на конференцији.

У то време, пројекат је већ добио ново име БИРМА, стекао разне додатне (не толико потпуно имплементиране, колико претпостављене) могућности - сви детаљи се могу наћи у мом извештају.

Да будем искрен, било је тешко назвати БИРМУ 2013 нечим комплетним; Искрено говорећи, то је био веома хаковски занат направљен на брзину. Што се тиче кода, практично уопште није било никаквих посебних иновација, осим прилично беспомоћног покушаја да се направи нека врста унифициране синтаксе за парсер, по изгледу који подсећа на језик форматирања ИРБИС 64 (а заправо и на систем ИСИС - са заградама као цикличним структурама; зашто сам у то време мислио да изгледа прилично кул). Парсер је безнадежно налетео на ове кругове заграда одговарајућег типа (пошто су заграде обављале и другу улогу, наиме, означавале су опционе структуре приликом рашчлањивања које се могу прескочити). Поново упућујем све који желе да се детаљније упознају са тада тешко замисливом, неоправданом синтаксом БИРМЕ на мој извештај из тог времена.

Генерално, осим што се мучим са сопственим парсером, немам више шта да кажем у вези са кодом ове верзије – осим обрнуте конверзије постојећих извора у Ц++ уз очување неких типичних карактеристика .НЕТ кода (да будем искрен, то је тешко разумети , шта ме је тачно подстакло да све вратим - вероватно неки глупи страх да своје изворне кодове чувам у тајности, као да је то нешто што је еквивалентно тајном рецепту Кока-коле).

Можда у овој глупој одлуци лежи и разлог за потешкоће у упаривању настале ДЛЛ библиотеке са постојећим интерфејсом домаће радне станице за унос података у електронски каталог (да, нисам споменуо још једну важну чињеницу: од сада ће сви код БИРМА „мотора“ је био очекиван, одвојен је од дела интерфејса и упакован у одговарајући ДЛЛ). Зашто је било потребно написати посебну радну станицу за ове сврхе, која је ионако по свом изгледу и начину интеракције са корисником бесрамно копирала исту радну станицу „Каталогизатор“ система ИРБИС 64 - ово је посебно питање. Укратко: дао је неопходну чврстину мојим тадашњим развојима за мој дипломски пројекат (иначе сам несварљиви механизам парсера некако није био довољан). Поред тога, тада сам наишао на неке потешкоће у имплементацији интерфејса Цаталогер радне станице са мојим сопственим модулима, имплементираним у Ц++ и Ц#, и директном приступу мом мотору.

Уопште, чудно, управо је овај прилично неспретни прототип будућег БИРМА.НЕТ-а био предодређен да постане мој „радни коњ“ у наредне четири године. Не може се рећи да за то време нисам бар покушао да пронађем путеве за нову, потпунију реализацију дугогодишње идеје. Између осталих иновација, већ је требало да постоје угнежђене цикличне секвенце које су могле да садрже опционе елементе – тако сам хтео да оживим идеју о ​​универзалним шаблонима за библиографске описе публикација и разне друге интересантне ствари. Међутим, у мојим тадашњим практичним активностима све је то било мало тражено, а имплементација коју сам имао у то време била је сасвим довољна за унос садржаја. Осим тога, вектор развоја наше библиотеке почео је све више да одступа ка дигитализацији музејске архиве, извештавању и другим активностима које ме мало занимају, што ме је на крају приморало да је коначно напустим, уступајући место онима који би будите задовољнији са свим овим .

Парадоксално, управо након ових драматичних догађаја пројекат БИРМА, који је тада већ имао све карактеристичне црте типичног дуготрајног пројекта, као да је почео да добија свој дуго очекивани нови живот! Имао сам више слободног времена за беспослене мисли, поново сам почео да чешљам светску мрежу у потрази за нечим сличним (на срећу, сада сам већ могао да претпоставим да све ово тражим не било где, већ на ГитХуб-у), а негде у почетком ове године коначно сам наишао на одговарајући производ познате компаније Салесфорце под безначајним именом Горп. Сам по себи, могао је да уради скоро све што ми је потребно од таквог парсер мотора - наиме, интелигентно изолује појединачне фрагменте од произвољног, али јасно структурираног текста, док има прилично једноставан интерфејс за крајњег корисника, укључујући такве разумљиве суштине, као што је образац, шаблон и појављивање, а притом се користи позната синтакса регуларних израза, која постаје неупоредиво читљивија због поделе на одређене семантичке групе за рашчлањивање.

Генерално, одлучио сам да је то тај Горп (Питам се шта ово име значи? Можда нека врста „опште оријентисаног редовног парсера“?) – управо оно што сам дуго тражио. Истина, његова непосредна имплементација за моје потребе имала је толики проблем да је овај механизам захтевао престрого придржавање структурног низа изворног текста. За неке извештаје као што су датотеке евиденције (наиме, поставили су их програмери као јасне примере коришћења пројекта), ово је сасвим прикладно, али за исте текстове скенираних табела садржаја, мало је вероватно. На крају крајева, иста страница са садржајем може почети речима „Садржај“, „Садржај“ и било којим другим прелиминарним описима које не треба да стављамо у резултате намераване анализе (и да их ручно одсечемо). сваки пут је такође незгодно). Поред тога, између појединачних понављајућих елемената, као што су име аутора, наслов и број странице, страница може садржати одређену количину смећа (на пример, цртеже и само насумичне знакове), што би такође било лепо да се може одрезати. Међутим, последњи аспект још није био толико значајан, али због првог, постојећа имплементација није могла да почне да тражи потребне структуре у тексту са одређеног места, већ га је једноставно обрадила од самог почетка, није пронашла прецизирао шаблоне и... завршио свој посао. Очигледно, било је потребно мало подешавања да би се барем оставио простор између структура које се понављају, и то ме је вратило на посао.

Други проблем је био тај што је сам пројекат имплементиран у Јави, и ако сам планирао у будућности да имплементирам неки начин повезивања ове технологије са познатим апликацијама за унос података у постојеће базе података (као што је Ирбисов „Каталог“), онда барем урадите ово у Ц# и .НЕТ. Није да је Јава сама по себи лош језик – једном сам је чак користио за имплементацију занимљиве прозорске апликације која је имплементирала функционалност домаћег програмабилног калкулатора (као део пројекта курса). И у смислу синтаксе, веома је сличан истом Ц-схарпу. Па, ово је само плус: лакше ће ми бити да финализујем постојећи пројекат. Међутим, нисам желео да поново урањам у овај прилично необичан свет прозорских (тачније десктоп) Јава технологија – уосталом, сам језик није био „скројен“ за такву употребу, а ја уопште нисам жудео за понављањем претходно искуство. Можда је то баш зато што је Ц# у комбинацији са ВинФормс-ом много ближи Делпхију, са којим су многи од нас некада почели. На срећу, потребно решење је пронађено прилично брзо – у виду пројекта ИКВМ.НЕТ, што олакшава превођење постојећих Јава програма у управљани .НЕТ код. Истина, сам пројекат је до тада већ био напуштен од стране аутора, али његова најновија имплементација ми је омогућила да прилично успешно изведем неопходне радње за изворне текстове Горп.

Тако да сам направио све потребне измене и све то саставио у ДЛЛ одговарајућег типа, који је лако могао да „покупи“ било који пројект за .НЕТ Фрамеворк креиран у Висуал Студио-у. У међувремену, направио сам још један слој за практичну презентацију враћених резултата Горп, у облику одговарајућих структура података које би било згодно обрадити у приказу табеле (узимајући за основу и редове и колоне; и кључеве речника и нумеричке индексе). Па, сами потребни услужни програми за обраду и приказивање резултата су написани прилично брзо.

Такође, процес прилагођавања шаблона за нови мотор како би га научио да анализира постојеће узорке скенираних текстова садржаја није изазвао посебне компликације. У ствари, нисам уопште морао да се позивам на своје претходне шаблоне: једноставно сам направио све потребне шаблоне од нуле. Штавише, ако су шаблони дизајнирани за рад са претходном верзијом система поставили прилично узак оквир за текстове који би се уз њихову помоћ могли правилно рашчланити, нови мотор је већ омогућио развој прилично универзалних шаблона погодних за неколико типова означавања на једном. Чак сам покушао да напишем неку врсту свеобухватног шаблона за било који произвољни текст са садржајем, иако, наравно, чак и са свим новим могућностима које су ми се отварале, укључујући, посебно, ограничену могућност имплементације истих угнежђених понављајућих секвенци ( као што су, на пример, презимена и иницијали неколико аутора у низу), испоставило се да је ово утопија.

Можда ће у будућности бити могуће имплементирати одређени концепт мета-шаблона, који ће моћи истовремено да провери изворни текст да ли је усклађен са неколико доступних шаблона, а затим, у складу са добијеним резултатима, изабере најпогоднији, користећи неку врсту интелигентног алгоритма. Али сада ме је више бринуло једно друго питање. Парсер као Горп, упркос својој свестраности и модификацијама које сам направио, и даље је инхерентно био неспособан да уради једну наизглед једноставну ствар коју је мој самописни парсер могао да уради од прве верзије. Наиме: имао је могућност да пронађе и издвоји из изворног текста све фрагменте који одговарају маски наведеној у оквиру шаблона који се користи на правом месту, а да га уопште не занима шта дати текст садржи у размацима између ових фрагмената. До сада сам само мало унапредио нови мотор, омогућавајући му да тражи сва могућа нова понављања датог низа таквих маски са тренутне позиције, остављајући могућност за присуство у тексту скупова произвољних знакова који су потпуно који нису узети у обзир у рашчлањивању, затворен између откривених понављајућих структура. Међутим, ово није омогућило постављање следеће маске без обзира на резултате претраживања претходног фрагмента помоћу одговарајуће маске: строгост описане структуре текста и даље није остављала простора за произвољно укључивање неправилних знакова.

И ако за примере табеле садржаја на које сам наишао овај проблем још није изгледао тако озбиљан, онда када покушавам да применим нови механизам рашчлањивања на сличан задатак рашчлањивања садржаја веб локације (тј. исто рашчлањивање), његов ограничења су се овде појавила са свом својом очигледношћу. На крају крајева, прилично је лако подесити потребне маске за фрагменте веб маркупа, између којих треба да се налазе подаци које тражимо (које треба издвојити), али како да натерамо парсер да одмах пређе на следећи сличан фрагмент, упркос свим могућим ознакама и ХТМЛ атрибутима који се могу поставити у размаке између њих?

После малог размишљања, одлучио сам да уведем неколико шема услуга (%алл_бефоре) и (%алл_афтер), служећи очигледној сврси да се осигура да се све што може бити садржано у изворном тексту прескочити пре било ког обрасца (маске) ​​који их прати. Штавише, ако (%алл_бефоре) једноставно игнорисао сва ова произвољна укључивања (%алл_афтер), напротив, омогућио је да се додају жељеном фрагменту након померања са претходног фрагмента. Звучи прилично једноставно, али да бих имплементирао овај концепт, морао сам поново да прочешљам Горпове изворе како бих направио неопходне модификације како не бих прекинуо већ имплементирану логику. На крају смо успели да то урадимо (иако је чак и прва, иако веома грешка, имплементација мог парсера написана, и то још брже - за неколико недеља). Од сада, систем је попримио заиста универзални облик - ни мање ни више од 12 година након првих покушаја да се учини да функционише.

Наравно, ово није крај наших снова. Такође можете потпуно преписати парсер Горп шаблона у Ц#, користећи било коју од доступних библиотека за имплементацију бесплатне граматике. Мислим да би код требало да буде значајно поједностављен, а то ће нам омогућити да се ослободимо наслеђа у облику постојећих Јава извора. Али са постојећим типом мотора такође је могуће урадити разне занимљиве ствари, укључујући покушај имплементације мета-шаблона које сам већ поменуо, а да не помињем рашчлањивање разних података са разних веб локација (међутим, не искључујем да су постојећи специјализовани софтверски алати погоднији за ово – само још нисам имао одговарајуће искуство у њиховом коришћењу).

Иначе, овог лета сам већ добио позив мејлом од компаније која користи Салесфорце технологије (програмер оригиналног Горп), проћи интервју за каснији рад у Риги. Нажалост, тренутно нисам спреман за такве прерасподеле.

Ако овај материјал изазове неко интересовање, онда ћу у другом делу покушати да детаљније опишем технологију за састављање и накнадно рашчлањивање шаблона на примеру имплементације која се користи у Салесфорце-у Горп (моји сопствени додаци, са изузетком неколико већ описаних функцијских речи, практично не уносе промене у саму синтакси шаблона, тако да скоро сва документација за оригинални систем Горп Погодно и за моју верзију).

Извор: ввв.хабр.цом

Додај коментар