Príbeh jedného malého projektu dlhého dvanásť rokov (o BIRMA.NET prvýkrát a úprimne z prvej ruky)

Zrod tohto projektu možno považovať za malý nápad, ktorý mi prišiel niekde na konci roku 2007, ktorý bol predurčený nájsť svoju finálnu podobu až o 12 rokov neskôr (v tomto momente – samozrejme, aj keď súčasná realizácia podľa pre autora je veľmi uspokojivá).

Všetko sa to začalo, keď som v rámci plnenia svojich vtedajších úradných povinností v knižnici upozornil na skutočnosť, že proces zadávania údajov z naskenovaného textu obsahových tabuliek knižných (a hudobných) publikácií do existujúcej databázy, resp. zjavne možno výrazne zjednodušiť a zautomatizovať s využitím vlastnosti usporiadanosti a opakovateľnosti všetkých údajov potrebných na zadanie, ako je meno autora článku (ak hovoríme o zbierke článkov), názov článok (alebo podnadpis uvedený v obsahu) a číslo strany aktuálnej položky obsahu. Spočiatku som bol prakticky presvedčený, že systém vhodný na realizáciu tejto úlohy sa dá ľahko nájsť na internete. Keď bolo prekvapenie spôsobené tým, že som takýto projekt nenašiel, rozhodol som sa, že ho skúsim zrealizovať sám.

Po pomerne krátkom čase začal fungovať prvý prototyp, ktorý som okamžite začal používať vo svojich každodenných činnostiach a súčasne som ho ladil na všetkých príkladoch, ktoré mi prišli pod ruku. Našťastie, na mojom bežnom pracovisku, kde som v žiadnom prípade nebol programátorom, mi potom ešte prešli viditeľné „prestoje“ v mojej práci, počas ktorých som intenzívne ladil svoje duchovné dieťa – čo je v súčasnej realite takmer nemysliteľné, čo znamená denné správy o práci vykonanej počas dňa. Proces vylepšovania programu trval celkovo nie menej ako asi rok, ale aj potom sa výsledok sotva dal nazvať úplne úspešným - existovalo príliš veľa rôznych konceptov, ktoré neboli celkom zrozumiteľné na implementáciu: voliteľné prvky, ktoré možno preskočiť ; prezeranie prvkov dopredu (na účely nahradenia predchádzajúcich prvkov vo výsledkoch vyhľadávania); dokonca aj náš vlastný pokus implementovať niečo ako regulárne výrazy (ktoré majú jedinečnú syntax). Musím povedať, že predtým som programovanie trochu vzdal (asi na 8 rokov, ak nie viac), takže nová príležitosť uplatniť svoje schopnosti na zaujímavej a potrebnej úlohe ma úplne zaujala. Nie je prekvapujúce, že výsledný zdrojový kód – pri absencii akýchkoľvek jasných prístupov k jeho dizajnu z mojej strany – sa pomerne rýchlo stal nepredstaviteľnou zmesou nesúrodých kúskov v jazyku C s niektorými prvkami C++ a aspektmi vizuálneho programovania (pôvodne to bolo rozhodnuté použiť taký návrhový systém ako Borland C++ Builder – „takmer Delphi, ale v C“). To všetko však v konečnom dôsledku prinieslo ovocie v automatizácii každodenných činností našej knižnice.

Zároveň som sa rozhodol pre každý prípad absolvovať kurzy na školenie profesionálnych vývojárov softvéru. Neviem, či sa tam vlastne dá naučiť „programátorom“ od nuly, ale vzhľadom na schopnosti, ktoré som v tom čase už mal, som do istej miery ovládal technológie, ktoré boli v tom čase relevantnejšie, napr. ako C#, Visual Studio pre vývoj pod .NET, ako aj niektoré technológie súvisiace s Java, HTML a SQL. Celé školenie trvalo celkovo dva roky a slúžilo ako východiskový bod pre ďalší môj projekt, ktorý sa nakoniec natiahol na niekoľko rokov – ale to je téma na samostatnú publikáciu. Tu by bolo vhodné poznamenať, že som sa pokúsil prispôsobiť vývoj, ktorý som už mal na popísanom projekte, aby som vytvoril plnohodnotnú okennú aplikáciu v C# a WinForms, ktorá implementuje potrebnú funkcionalitu, a použil ju ako základ pre pripravovaný diplomový projekt.
Postupom času sa mi táto myšlienka začala zdať hodná vyjadrenia na takých výročných konferenciách za účasti predstaviteľov rôznych knižníc ako „LIBKOM“ a „CRIMEA“. Myšlienka áno, ale nie moja vtedajšia realizácia. Potom som tiež dúfal, že to niekto prepíše pomocou kompetentnejších prístupov. Tak či onak, do roku 2013 som sa rozhodol napísať správu o svojej prípravnej práci a poslať ju Organizačnému výboru konferencie so žiadosťou o grant na účasť na konferencii. Na moje mierne prekvapenie bola moja žiadosť schválená a začal som robiť nejaké vylepšenia projektu, aby som ho pripravil na prezentáciu na konferencii.

V tom čase už projekt dostal nový názov BIRMA, získal rôzne dodatočné (nie tak úplne implementované, ale skôr predpokladané) schopnosti - všetky podrobnosti nájdete v mojej správe.

Úprimne povedané, bolo ťažké nazvať BIRMU 2013 niečím úplným; Úprimne povedané, bolo to veľmi špinavé remeslo vyrobené v zhone. Pokiaľ ide o kód, prakticky nedošlo k žiadnym špeciálnym inováciám, s výnimkou dosť bezmocného pokusu o vytvorenie akejsi jednotnej syntaxe pre syntaktický analyzátor vzhľadom pripomínajúci formátovací jazyk IRBIS 64 (a vlastne aj systém ISIS - so zátvorkami ako cyklickými štruktúrami; prečo V tom čase som si myslel, že to vyzerá celkom dobre). Syntaktický analyzátor beznádejne narazil na tieto kruhy zátvoriek príslušného typu (keďže zátvorky plnili aj inú úlohu, a to označovali voliteľné štruktúry počas analýzy, ktoré je možné preskočiť). Všetkých, ktorí sa chcú s vtedajšou ťažko predstaviteľnou, neopodstatnenou syntaxou BIRMA bližšie zoznámiť, opäť odkazujem na moju vtedajšiu správu.

Vo všeobecnosti, okrem boja s vlastným parserom, nemám čo povedať ku kódu tejto verzie - okrem spätnej konverzie existujúcich zdrojov do C++ pri zachovaní niektorých typických vlastností kódu .NET (aby som bol úprimný, je to ťažko pochopiteľné, čo ma presne podnietilo presunúť všetko späť - pravdepodobne nejaký hlúpy strach z utajenia mojich zdrojových kódov, ako keby to bolo niečo ekvivalentné tajnému receptu Coca-Coly).

Možno v tomto hlúpom rozhodnutí sú aj ťažkosti pri spárovaní výslednej DLL knižnice s existujúcim rozhraním podomácky vyrobenej pracovnej stanice na zadávanie údajov do elektronického katalógu (áno, nespomenul som ešte jeden dôležitý fakt: odteraz budú všetky kód „engine“ BIRMA bol podľa očakávania, je oddelený od časti rozhrania a zabalený v príslušnej knižnici DLL). Prečo bolo potrebné na tieto účely napísať samostatnú pracovnú stanicu, ktorá aj tak svojím vzhľadom a spôsobom interakcie s používateľom bez hanby kopírovala rovnakú pracovnú stanicu „Katalogizátor“ systému IRBIS 64 - to je samostatná otázka. Stručne povedané: dodalo to potrebnú pevnosť môjmu vtedajšiemu vývoju pre môj diplomový projekt (inak samotný nestráviteľný syntaktický engine akosi nestačil). Okrem toho som sa potom stretol s určitými ťažkosťami pri implementácii rozhrania pracovnej stanice Cataloger s mojimi vlastnými modulmi implementovanými v C++ aj C# a priamom prístupe k môjmu enginu.

Vo všeobecnosti, napodiv, to bol tento dosť nemotorný prototyp budúceho BIRMA.NET, ktorý bol predurčený stať sa mojím „pracovným koňom“ na ďalšie štyri roky. Nedá sa povedať, že by som sa za tento čas aspoň nesnažil nájsť cesty pre novú, ucelenejšiu realizáciu dlhoročného nápadu. Okrem iných inovácií tu už mali byť vnorené cyklické sekvencie, ktoré mohli obsahovať voliteľné prvky – takto som chcel uviesť do života myšlienku ​univerzálnych šablón pre bibliografické popisy publikácií a rôzne iné zaujímavosti. V mojej praktickej činnosti v tom čase však bolo toto všetko málo žiadané a implementácia, ktorú som mal vtedy, úplne postačovala na zadávanie obsahov. Navyše, vektor rozvoja našej knižnice sa začal čoraz viac odkláňať smerom k digitalizácii múzejných archívov, spravodajstvu a iným pre mňa málo zaujímavým činnostiam, čo ma nakoniec prinútilo ju napokon opustiť a ustúpiť tým, ktorí by buď s tým všetkým viac spokojný.

Paradoxne práve po týchto dramatických udalostiach sa zdalo, že projekt BIRMA, ktorý už v tom čase mal všetky charakteristické znaky typického dlhodobého stavebného projektu, začal naberať svoj dlho očakávaný nový život! Mal som viac voľného času na nečinné myšlienky, opäť som začal prečesávať World Wide Web pri hľadaní niečoho podobného (našťastie, teraz som už tušil, že to všetko budem hľadať nielen kdekoľvek, ale na GitHub) a niekde v At the začiatkom tohto roka som konečne natrafil na zodpovedajúci produkt od známej firmy Salesforce pod bezvýznamným názvom Gorp. Sama o sebe dokázala robiť takmer všetko, čo som od takéhoto analyzátora potreboval – konkrétne inteligentne izolovať jednotlivé fragmenty od ľubovoľného, ​​ale jasne štruktúrovaného textu, pričom má pre koncového používateľa pomerne užívateľsky prívetivé rozhranie, vrátane takých zrozumiteľných esencií, ako je napr. vzor, ​​šablónu a výskyt a zároveň využíva známu syntax regulárnych výrazov, ktorá sa vďaka rozdeleniu do určených sémantických skupín na analýzu stáva neporovnateľne čitateľnejšou.

Vo všeobecnosti som sa rozhodol, že toto je ten pravý Gorp (Zaujímalo by ma, čo tento názov znamená? Možno nejaký „všeobecne orientovaný pravidelný analyzátor“?) – presne to, čo som dlho hľadal. Pravda, jeho okamžitá implementácia pre vlastnú potrebu mala taký problém, že tento engine si vyžadoval príliš prísne dodržanie štruktúrnej postupnosti zdrojového textu. Pre niektoré správy, ako sú napríklad súbory denníka (konkrétne ich vývojári umiestnili ako jasné príklady použitia projektu), je to celkom vhodné, ale pre rovnaké texty naskenovaných obsahov je to nepravdepodobné. Koniec koncov, tá istá stránka s obsahom môže začínať slovami „Obsah“, „Obsah“ a akýmikoľvek ďalšími predbežnými popismi, ktoré nemusíme umiestňovať do výsledkov zamýšľanej analýzy (a ručne ich orezávať zakaždým je to tiež nepohodlné). Okrem toho medzi jednotlivými opakujúcimi sa prvkami, ako je meno autora, názov a číslo strany, môže stránka obsahovať určité množstvo odpadu (napríklad kresby a len náhodné znaky), ktoré by bolo tiež pekné odrezať. Posledný aspekt však ešte nebol taký výrazný, no kvôli prvému nemohla existujúca implementácia začať hľadať potrebné štruktúry v texte od určitého miesta, ale namiesto toho ho jednoducho spracovala od samého začiatku, nenašla špecifikoval tam vzory a... ukončil moju prácu. Je zrejmé, že bolo potrebné vyladiť aspoň nejaký priestor medzi opakujúcimi sa štruktúrami, a to ma vrátilo do práce.

Ďalším problémom bolo, že samotný projekt bol implementovaný v jazyku Java, a ak by som v budúcnosti plánoval implementovať nejaké prostriedky na prepojenie tejto technológie so známymi aplikáciami na zadávanie údajov do existujúcich databáz (napríklad Irbis’s “Cataloguer”), tak aspoň aspoň urobte to v C# a .NET. Nie je to tak, že by samotná Java bola zlý jazyk – raz som ju dokonca použil na implementáciu zaujímavej okennej aplikácie, ktorá implementovala funkcionalitu domácej programovateľnej kalkulačky (ako súčasť projektu kurzu). A z hľadiska syntaxe je veľmi podobný rovnakému C-sharp. No, to je len plus: o to ľahšie bude pre mňa dokončiť existujúci projekt. Nechcel som sa však znova vrhnúť do tohto dosť nezvyčajného sveta okenných (alebo skôr desktopových) Java technológií - koniec koncov, jazyk sám o sebe nebol „šitý“ na takéto použitie a vôbec som netúžil po opakovaní predchádzajúce skúsenosti. Možno práve preto, že C# v spojení s WinForms je oveľa bližšie k Delphi, s ktorým mnohí z nás kedysi začínali. Našťastie sa potrebné riešenie našlo pomerne rýchlo – v podobe projektu IKVM.NET, čo uľahčuje preklad existujúcich programov Java do spravovaného kódu .NET. Je pravda, že samotný projekt už autori v tom čase opustili, ale jeho posledná implementácia mi umožnila celkom úspešne vykonať potrebné akcie pre zdrojové texty Gorp.

Urobil som teda všetky potrebné zmeny a skompiloval som to všetko do knižnice DLL vhodného typu, ktorú by mohli ľahko „zobrať“ všetky projekty pre .NET Framework vytvorené vo Visual Studiu. Medzitým som vytvoril ďalšiu vrstvu na pohodlnú prezentáciu vrátených výsledkov Gorpvo forme zodpovedajúcich dátových štruktúr, ktoré by bolo vhodné spracovať v tabuľkovom zobrazení (za základ riadky aj stĺpce; kľúče slovníka aj číselné indexy). No a samotné potrebné utility na spracovanie a zobrazenie výsledkov boli napísané pomerne rýchlo.

Ani proces prispôsobovania šablón pre nový engine s cieľom naučiť ho analyzovať existujúce vzorky naskenovaných textov obsahu nespôsobil žiadne zvláštne komplikácie. V skutočnosti som sa ani nemusel odvolávať na svoje predchádzajúce šablóny: jednoducho som vytvoril všetky potrebné šablóny od začiatku. Navyše, ak šablóny navrhnuté na prácu s predchádzajúcou verziou systému nastavili dosť úzky rámec pre texty, ktoré by sa s ich pomocou dali správne analyzovať, nový engine už umožnil vyvinúť pomerne univerzálne šablóny vhodné pre niekoľko typov značiek na raz. Dokonca som sa pokúsil napísať nejakú komplexnú šablónu pre ľubovoľný text obsahu, aj keď, samozrejme, aj so všetkými novými možnosťami, ktoré sa mi otvárajú, vrátane najmä obmedzenej schopnosti implementovať rovnaké vnorené opakujúce sa sekvencie ( ako sú napríklad priezviská a iniciály viacerých autorov za sebou), to sa ukázalo ako utópia.

Možno v budúcnosti bude možné implementovať určitú koncepciu metašablón, ktorá bude schopná kontrolovať súlad zdrojového textu s niekoľkými dostupnými šablónami naraz a potom v súlade so získanými výsledkami vybrať najvhodnejší pomocou nejakého druhu inteligentného algoritmu. Ale teraz ma viac znepokojovala iná otázka. Ako analyzátor Gorp, napriek všetkej svojej všestrannosti a úpravám, ktoré som urobil, stále nebol vo svojej podstate schopný urobiť jednu zdanlivo jednoduchú vec, ktorú môj vlastný analyzátor dokázal urobiť od úplne prvej verzie. Totiž: mal schopnosť nájsť a vytiahnuť zo zdrojového textu všetky fragmenty, ktoré zodpovedajú maske špecifikovanej v použitej šablóne na správnom mieste, pričom ho vôbec nezaujímalo, čo daný text obsahuje v medzerách medzi týmito fragmentmi. Zatiaľ som len mierne vylepšil nový engine, ktorý mu umožňuje hľadať všetky možné nové opakovania danej sekvencie takýchto masiek z aktuálnej pozície, ponechávajúc možnosť pre prítomnosť v texte množín ľubovoľných znakov, ktoré boli úplne nezohľadnené pri analýze, uzavreté medzi detekovanými opakujúcimi sa štruktúrami. To však neumožnilo nastaviť ďalšiu masku bez ohľadu na výsledky hľadania predchádzajúceho fragmentu pomocou zodpovedajúcej masky: prísnosť opísanej štruktúry textu stále nenechávala priestor pre svojvoľné zaraďovanie nepravidelných znakov.

A ak sa pre príklady obsahov, s ktorými som sa stretol, tento problém ešte nezdal taký závažný, potom pri pokuse použiť nový mechanizmus analýzy na podobnú úlohu analýzy obsahu webovej stránky (t. j. rovnakú analýzu) obmedzenia sú tu, objavili sa so všetkou svojou samozrejmosťou. Koniec koncov, je celkom jednoduché nastaviť potrebné masky pre fragmenty webových značiek, medzi ktorými by sa mali nachádzať údaje, ktoré hľadáme (ktoré je potrebné extrahovať), ale ako prinútiť analyzátor okamžite prejsť na ďalšiu podobný fragment, napriek všetkým možným značkám a atribútom HTML, ktoré možno umiestniť do medzier medzi nimi?

Po krátkom premýšľaní som sa rozhodol zaviesť niekoľko vzorov služieb (%all_before) и (%all_after), slúžiacemu očividnému účelu zabezpečiť, že všetko, čo môže byť obsiahnuté v zdrojovom texte, bude preskočené pred akýmkoľvek vzorom (maskou), ktorý za nimi nasleduje. Navyše, ak (%all_before) jednoducho ignoroval všetky tieto svojvoľné inklúzie (%all_after), naopak, umožnilo ich pridanie k požadovanému fragmentu po presune z predchádzajúceho fragmentu. Znie to celkom jednoducho, ale na implementáciu tohto konceptu som musel znova prečesať zdroje gorpu, aby som urobil potrebné úpravy, aby som neporušil už implementovanú logiku. Nakoniec sa nám to podarilo (hoci bola napísaná aj úplne prvá, aj keď veľmi zabugovaná implementácia môjho syntaktického analyzátora, a to ešte rýchlejšie - za pár týždňov). Odteraz nadobudol systém skutočne univerzálnu podobu – nie menej ako 12 rokov po prvých pokusoch o jeho fungovanie.

Samozrejme, toto nie je koniec našich snov. Môžete tiež úplne prepísať analyzátor šablóny gorp v C# pomocou ktorejkoľvek z dostupných knižníc na implementáciu bezplatnej gramatiky. Myslím si, že kód by sa mal výrazne zjednodušiť a to nám umožní zbaviť sa dedičstva v podobe existujúcich zdrojov Java. Ale s existujúcim typom enginu sa dajú celkom dobre robiť aj rôzne zaujímavosti, vrátane pokusu o implementáciu už spomínaných metašablón, nehovoriac o parsovaní rôznych dát z rôznych webov (nevylučujem však že existujúce špecializované softvérové ​​nástroje sú na to vhodnejšie – len som ešte nemal dostatočné skúsenosti s ich používaním).

Mimochodom, toto leto som už dostal e-mailom pozvánku od spoločnosti, ktorá používa technológie Salesforce (vývojár originálu Gorp), absolvovať pohovor pre ďalšiu prácu v Rige. Žiaľ, momentálne nie som pripravený na takéto presuny.

Ak tento materiál vzbudí záujem, tak sa v druhej časti pokúsim podrobnejšie popísať technológiu kompilácie a následne parsovania šablón na príklade implementácie použitej v Salesforce Gorp (moje vlastné doplnky, s výnimkou niekoľkých už popísaných funkčných slov, nerobia prakticky žiadne zmeny v samotnej syntaxi šablóny, takže takmer všetka dokumentácia k pôvodnému systému Gorp Vhodné aj pre moju verziu).

Zdroj: hab.com

Pridať komentár