A storia di un picculu prughjettu di dodici anni (circa BIRMA.NET per a prima volta è francamente di prima manu)

A nascita di stu prughjettu pò esse cunsideratu una piccula idea chì m'hà vinutu in qualchì locu à a fine di u 2007, chì era destinatu à truvà a so forma finali solu 12 anni dopu (à questu puntu in u tempu - di sicuru, ancu s'è l'implementazione attuale, sicondu à l'autore, hè assai soddisfacente).

Tuttu hà cuminciatu quandu, in u prucessu di cumpiendu i mo duveri ufficiali in a biblioteca, aghju attiratu l'attenzione à u fattu chì u prucessu di inserisce dati da u testu scansatu di e tavule di cuntenutu di publicazioni di libri (è di musica) in a basa di dati esistenti. apparentemente, pò esse significativamente simplificatu è automatizatu, apprufittannu di a pruprietà di l'ordine è a ripetibilità di tutti i dati necessarii per l'input, cum'è u nome di l'autore di l'articulu (se parlemu di una cullizzioni di articuli), u titulu di l'articulu (o u subtitulu riflessu in a tabella di cuntenutu) è u numeru di pagina di l'articulu di u cuntenutu attuale. À u principiu, era praticamente cunvinta chì un sistema adattatu per realizà stu compitu puderia esse facilmente truvatu in Internet. Quandu una certa sorpresa hè stata causata da u fattu chì ùn aghju micca pussutu truvà un tali prughjettu, decisu di pruvà à implementà per mè stessu.

Dopu un pocu tempu, u primu prototipu hà cuminciatu à travaglià, chì aghju cuminciatu immediatamente à aduprà in e mo attività di ogni ghjornu, debugging simultaneamente nantu à tutti l'esempii chì sò venuti à a mo manu. Fortunatamente, in u mo locu di travagliu abituale, induve ùn era micca un programatore, aghju ancu scappatu cù "tempi d'inattività" visibili in u mo travagliu, durante u quali aghju debugging intensamente a mo idea - una cosa quasi impensabile in a realità attuale, chì implica. rapporti ogni ghjornu nantu à u travagliu fattu durante u ghjornu. U prucessu di lucidatura di u prugramma hà pigliatu un totale di micca menu di circa un annu, ma ancu dopu chì u risultatu ùn pò micca esse chjamatu cumplettamente successu - sò stati inizialmente stabiliti troppu cuncetti diffirenti chì ùn sò micca sanu sanu chjaru per l'implementazione: elementi facultativi chì ponu esse saltatu; visualizazione in avanti di elementi (per u scopu di rimpiazzà elementi precedenti in risultati di ricerca); ancu u nostru propiu tentativu di implementà qualcosa cum'è espressioni regulari (chì hà una sintassi unica). Devu dì chì prima di questu aghju rinunciatu un pocu di prugrammazione (per circa 8 anni, se micca più), cusì a nova opportunità di applicà e mo cumpetenze à un compitu interessante è necessariu hà catturatu cumplettamente a mo attenzione. Ùn hè micca surprisante chì u codice fonte resultanti - in l'absenza di qualsiasi approcciu chjaru à u so disignu da a mo parte - hè diventatu abbastanza rapidamente un mischmash inimaginable di pezzi disparati in a lingua C cù certi elementi di C++ è aspetti di prugrammazione visuale (inizialmente. Hè statu decisu di utilizà un sistema di cuncepimentu cum'è Borland C++ Builder - "quasi Delphi, ma in C"). In ogni casu, tuttu questu ultimamente hà purtatu fruttu in l'automatizazione di l'attività di ogni ghjornu di a nostra biblioteca.

À u listessu tempu, aghju decisu, solu in casu, di piglià corsi per furmà sviluppatori di software prufessiunali. Ùn sò micca sapè s'ellu hè veramente pussibule d'amparà "per esse un programatore" da zero quì, ma tenendu in contu e cumpetenze ch'e aghju digià avutu in quellu tempu, aghju sappiutu un pocu maestru di tecnulugia chì era più pertinenti à quellu tempu, cusì cum'è C#, Visual Studio per u sviluppu sottu .NET, è ancu alcune tecnulugia ligati à Java, HTML è SQL. A furmazione tutale hà pigliatu un totale di dui anni, è hà servitu cum'è u puntu di partenza per un altru prughjettu di u mio, chì ultimamente si stende nantu à parechji anni - ma questu hè un tema per una publicazione separata. Quì saria solu apprupriatu à nutà chì aghju fattu un tentativu di adattà i sviluppi chì aghju digià avutu nantu à u prughjettu descrittu per creà una applicazione di finestra cumpleta in C# è WinForms chì implementa a funziunalità necessaria, è l'utilizanu cum'è a basa per u prughjettu di diploma in u futuru.
À u tempu, sta idea hà cuminciatu à mi pare degna di esse espressa in tali cunferenze annuali cù a participazione di rapprisentanti di diverse biblioteche cum'è "LIBKOM" è "CRIMEA". L'idea, sì, ma micca a mo implementazione in quellu tempu. Allora sperava ancu chì qualcunu l'avessi riscrivite utilizendu approcci più cumpetenti. In un modu o un altru, da 2013, aghju decisu di scrive un rapportu nantu à u mo travagliu preliminare è di mandà à u Cumitatu d'Organizazione di a Conferenza cù una dumanda per una cuncessione per participà à a cunferenza. À a mo sorpresa un pocu, a mo applicazione hè stata appruvata, è aghju cuminciatu à fà alcune migliure à u prugettu per preparà per a presentazione à a cunferenza.

À quellu tempu, u prugettu avia digià ricivutu un novu nome BIRMA, hà acquistatu diverse capacità supplementari (micca assai implementate, ma piuttostu assulutu) - tutti i dettagli ponu esse truvati in u mo rapportu.

Per esse onesto, era difficiule di chjamà BIRMA 2013 qualcosa cumpletu; Francamente parlante, era un mistieru assai pirate fattu in fretta. In termini di codice, ùn ci era praticamente nisuna innovazioni spiciali, eccettu per un tentativu piuttostu impotente di creà una sintassi unificata per l'analizzatore, in l'apparenza chì ricorda a lingua di formattazione IRBIS 64 (è in fatti, ancu u sistema ISIS - cù parentesi cum'è strutture cicliche; perchè A l'epica aghju pensatu chì pareva bellu bellu). L'analizzatore hà sbulicatu senza speranza nantu à questi circles di parentesi di u tipu appropritatu (perchè i parentesi anu ancu fattu un altru rolu, à dì, anu marcatu strutture facultative durante l'analisi chì ponu esse saltate). Riferisce di novu tutti quelli chì volenu cunnosce a sintassi allora difficiuli di imaginà, inghjustificate di BIRMA in più detail à u mo rapportu di quellu tempu.

In generale, fora di luttà cù u mo parser, ùn aghju nunda di più à dì riguardu à u codice di sta versione - eccettu per a cunversione inversa di e fonti esistenti in C ++ mentre priservendu alcune caratteristiche tipiche di u codice .NET (per esse onesto, hè difficiuli di capiscenu, ciò chì esattamente m'hà incitatu à spustà tuttu in daretu - probabilmente una paura stupida di mantene i mo codici fonte sicreti, cum'è s'ellu era qualcosa equivalente à a ricetta secreta di Coca-Cola).

Forse sta decisione stupida hè ancu u mutivu di e difficultà in accoppià a biblioteca DLL risultante cù l'interfaccia esistente di una stazione di travagliu fatta in casa per inserisce dati in un catalogu elettronicu (iè, ùn aghju micca dettu un altru fattu impurtante: da avà, tutti u codice di u "motore" BIRMA era cum'è s'aspittava, hè siparatu da a parte di l'interfaccia è imballata in u DLL apprupriatu). Perchè era necessariu di scrive una stazione di travagliu separata per questi scopi, chì in ogni modu, in u so aspettu è u metudu d'interazzione cù l'utilizatore, copiò senza vergogna a stessa stazione di travagliu "Catalogizer" di u sistema IRBIS 64 - questa hè una quistione separata. In corta: hà datu a solidità necessaria à i mo sviluppi allora per u mo prughjettu di graduazione (altrimenti u mutore parser indigestible solu ùn era micca abbastanza). Inoltre, aghju scontru qualchì difficultà à implementà l'interfaccia di a stazione di travagliu di u Catalogu cù i mo propri moduli, implementati in C++ è C#, è accede direttamente à u mo mutore.

In generale, stranamente, era stu prototipu piuttostu goffo di u futuru BIRMA.NET chì era destinatu à diventà u mo "cavallu di travagliu" per i quattru anni dopu. Ùn si pò dì chì durante stu tempu ùn aghju micca almenu pruvatu à truvà modi per una implementazione nova è più cumpleta di una idea longa. Frà l'altri innuvazioni, duverebbe esse digià sequenze cicliche nidificate chì puderianu includere elementi facultativi - questu hè cumu aghju da fà vita l'idea di mudelli universali per descrizzioni bibliografiche di publicazioni è parechje altre cose interessanti. In ogni casu, in e mo attività pratiche in quellu tempu, tuttu questu era pocu dumanda, è l'implementazione ch'e aghju avutu in quellu tempu era abbastanza abbastanza per entra in tavule di cuntenutu. In più, u vettore di sviluppu di a nostra biblioteca hà cuminciatu à svià sempre più versu a digitalizazione di l'archivi di i musei, i rappurtazioni è altre attività di pocu interessu per mè, chì à a fine m'hà obligatu à lascià infine, lascendu a strada à quelli chì vulianu. esse più piacè di tuttu questu.

Paradoxalmente, era dopu à sti avvenimenti drammatici chì u prughjettu BIRMA, chì in quellu tempu avia digià tutte e caratteristiche caratteristiche di un prughjettu di custruzzione tipica à longu andà, pareva principià à piglià a so nova vita aspittata! Aviu avutu più tempu liberu per i pinsamenti inattivi, aghju cuminciatu di novu à pettinà u World Wide Web in cerca di qualcosa simili (per furtuna, avà puderia digià indovinà di circà tuttu questu micca solu in ogni locu, ma in GitHub), è in qualchì locu in At the A principiu di questu annu, aghju infine scontru un pruduttu currispundenti da a famosa cumpagnia di Salesforce sottu u nome insignificante. Gorp. Per ellu stessu, puderia fà quasi tuttu ciò chì avia bisognu di un tali mutore di parser - vale à dì, isolà in modu intelligente i frammenti individuali da testu arbitrariu, ma chjaramente strutturatu, mentre avè una interfaccia abbastanza amichevule per l'utilizatore finale, cumprese essenze cusì comprensibili, cum'è un mudellu, mudellu è occurrence, è à u stessu tempu utilizendu a sintassi familiare di l'espressioni regulare, chì diventa incomparablemente più leggibile per via di a divisione in gruppi semantichi designati per l'analisi.

In generale, aghju decisu chì questu hè quellu Gorp (Mi dumandu ciò chì significa stu nome? Forse un tipu di "parser regulare orientatu generale"?) - esattamente ciò chì aghju cercatu per un bellu pezzu. Hè veru, a so implementazione immediata per i mo bisogni hà avutu un prublema cusì chì stu mutore necessitava aderenza troppu stretta à a sequenza strutturale di u testu fonte. Per certi rapporti, cum'è i schedarii di log (vale à dì, sò stati posti da i sviluppatori cum'è esempi chjaru di usu di u prugettu), questu hè abbastanza adattatu, ma per i stessi testi di tavule di cuntenutu scansatu, hè improbabile. Dopu tuttu, a stessa pagina cù una tavola di cuntenutu pò principià cù e parolle "Table of Contents", "Contents" è qualsiasi altre descrizzioni preliminari chì ùn avemu micca bisognu di mette in i risultati di l'analisi previstu (è tagliate manualmente). ogni volta hè ancu inconveniente). Inoltre, trà elementi ripetuti individuali, cum'è u nome di l'autore, u tìtulu è u numeru di pagina, a pagina pò cuntene una certa quantità di basura (per esempiu, disegni, è solu caratteri aleatori), chì saria ancu bellu di pudè. taglià. In ogni casu, l'ultimu aspettu ùn era ancu cusì significativu, ma per via di u primu, l'implementazione esistente ùn pudia micca principià à circà e strutture necessarie in u testu da un certu locu, ma invece simpricimenti processatu da u principiu, ùn hà micca truvatu u mudelli specificati quì è ... finitu u mo travagliu. Ovviamente, qualchì tweaking era necessariu per almenu permette un pocu di spaziu trà e strutture ripetitive, è chì m'hà tornatu à u travagliu.

Un altru prublema era chì u prughjettu stessu hè statu implementatu in Java, è s'è aghju pensatu in u futuru à implementà qualchì mezzu di interfaccia di sta tecnulugia cù applicazioni familiari per inserisce dati in basa di dati esistenti (cum'è "Catalogue" di Irbis), almenu almenu. fate questu in C# è .NET. Ùn hè micca chì Java stessu hè una lingua cattiva - una volta l'aghju ancu utilizatu per implementà una interessante applicazione di finestra chì implementava a funziunalità di una calculatrice programable domestica (cum'è parte di un prughjettu di cursu). È in termini di sintassi hè assai simili à u listessu C-sharp. Ebbè, questu hè solu un plus: u più faciule serà per mè finalizà un prughjettu esistente. Tuttavia, ùn aghju micca vulsutu immergervi di novu in stu mondu insolitu di Windows (o piuttostu, desktop) tecnulugii Java - dopu à tuttu, a lingua stessa ùn era micca "adattata" per un tali usu, è ùn aghju micca in tuttu brama una ripetizione di l'esperienza precedente. Forsi hè precisamente perchè C# in cunghjunzione cù WinForms hè assai più vicinu à Delphi, cù quale parechji di noi avemu principiatu. Fortunatamente, a suluzione necessaria hè stata truvata abbastanza rapidamente - in a forma di u prugettu IKVM.NET, chì facilita a traduzzione di prugrammi Java esistenti in codice .NET amministratu. Hè veru, u prugettu stessu era digià abbandunatu da l'autori à quellu tempu, ma a so ultima implementazione m'hà permessu di realizà bè bè l'azzioni necessarii per i testi fonte. Gorp.

Allora aghju fattu tutti i cambiamenti necessarii è assemblatu tuttu in una DLL di u tipu appropritatu, chì puderia esse facilmente "cogliu" da qualsiasi prughjetti per u .NET Framework creatu in Visual Studio. Intantu, aghju creatu una altra capa per a presentazione conveniente di i risultati tornati Gorp, in a forma di strutture di dati currispundenti chì saria cunvene per processà in una vista di tavula (pigliendu com'è una basa sia fila è culonni; sia chjave di dizziunariu sia indici numerichi). Ebbè, i utilità necessarii stessi per processà è affissà i risultati ottenuti eranu digià scritti abbastanza rapidamente.

Inoltre, u prucessu di adattazione di mudelli per u novu mutore per insegnà à analizà i campioni esistenti di testi scannati di tavule di cuntenutu ùn hà micca causatu cumplicazioni spiciali. In fatti, ùn aghju mancu bisognu di riferite à i mo mudelli precedenti: aghju creatu solu tutti i mudelli necessarii da zero. Inoltre, se i mudelli pensati per travaglià cù a versione precedente di u sistema stabiliscenu un quadru abbastanza strettu per i testi chì puderanu esse analizati currettamente cù u so aiutu, u novu mutore hà digià permessu di sviluppà mudelli abbastanza universali adattati per parechji tipi di marcatura una volta. Aghju ancu pruvatu à scrive un tipu di mudellu cumpletu per qualsiasi testu di u cuntenutu arbitrariu, ancu s'ellu, sicuru, ancu cù tutte e novi pussibulità chì si aprenu per mè, cumprese, in particulare, a capacità limitata di implementà e stesse sequenze ripetute nidificate ( cum'è, per esempiu, cognomi è iniziali parechji autori in una fila), questu hè diventatu una utopia.

Forsi in u futuru serà pussibule implementà un certu cuncettu di meta-templates, chì puderà verificà u testu fonte per u rispettu di parechji mudelli dispunibuli à una volta, è dopu, in cunfurmità cù i risultati ottenuti, selezziunate u u più adattatu, utilizendu un algoritmu intelligente. Ma avà era più preoccupatu per una altra quistione. Un parser cum'è Gorp, Malgradu tutta a so versatilità è e mudificazioni ch'e aghju fattu, era ancu intrinsecamente incapace di fà una cosa apparentemente simplice chì u mo parser auto-scrittu hà sappiutu fà da a prima versione. Vale à dì: hà avutu a capacità di truvà è estrae da u testu fonte tutti i frammenti chì currispondenu à a maschera specificata in u mudellu utilizatu in u locu ghjustu, mentre ùn era micca interessatu in ciò chì u testu datu cuntene in i spazii trà questi frammenti. Finu a ora, aghju solu ligeramente migliuratu u novu mutore, chì permette di circà tutte e pussibuli novi ripetizioni di una sequenza data di tali maschere da a pusizione attuale, lascendu a pussibilità di a prisenza in u testu di setti di caratteri arbitrarii chì eranu cumpletamente. unaccounted for in the parsing, inclosed between the detected repeating structures. In ogni casu, questu ùn hà micca permessu di stabilisce a prossima maschera, indipendentemente da i risultati di a ricerca di u frammentu precedente utilizendu a maschera currispondente: a rigurosità di a struttura di testu descritta ùn hà micca lasciatu spaziu per l'inclusioni arbitrarie di caratteri irregulari.

E se per l'esempii di tavule di cuntenutu chì aghju scontru stu prublema ùn pareva micca cusì seriu, allora quandu pruvate d'applicà un novu mecanismu di analisi à un compitu simili di analizà u cuntenutu di un situ web (vale à dì a stessa analisi), u so limitazioni sò quì apparsu cù tutte e so ovviousness. Dopu tuttu, hè abbastanza faciule per stabilisce e maschere necessarie per i frammenti di marcatura web, trà quale i dati chì avemu cercatu (chì deve esse estratti) deve esse situatu, ma cumu pudemu furzà u parser per passà immediatamente à u prossimu. frammentu simili, malgradu tutti i tags pussibuli è l'attributi HTML chì ponu esse posti in i spazii trà elli?

Dopu avè pensatu un pocu, decisu di presentà un paru di mudelli di serviziu (% all_before) и (% all_dopu), chì serve u scopu evidenti di assicurà chì tuttu ciò chì pò esse cuntenutu in u testu fonte hè saltatu prima di qualsiasi mudellu (mascara) chì seguitanu. Inoltre, se (% all_before) simpricimenti ignoratu tutte queste inclusioni arbitrarie, allora (% all_dopu), à u cuntrariu, hà permessu di aghjunghje à u frammentu desideratu dopu avè spusatu da u fragmentu precedente. Sembra abbastanza sèmplice, ma per implementà stu cuncettu aghju avutu à pettine à e fonti di Gorp di novu per fà e mudificazioni necessarie per ùn rompe a logica digià implementata. In fine, avemu riesciutu à fà questu (ancu ancu u primu, assai prima, ancu assai buggy, l'implementazione di u mo parser hè stata scritta, è ancu più veloce - in un paru di settimane). Da avà, u sistema hà pigliatu una forma veramente universale - micca menu di 12 anni dopu à i primi tentativi di fà funziona.

Di sicuru, questu ùn hè micca a fine di i nostri sogni. Pudete ancu riscrive completamente l'analizzatore di mudelli Gorp in C#, usendu qualsiasi di e librerie dispunibili per implementà una grammatica libera. Pensu chì u codice deve esse simplificatu significativamente, è questu ci permetterà di sguassà u legatu in forma di fonti Java esistenti. Ma cù u tipu di mutore esistente, hè ancu abbastanza pussibule di fà diverse cose interessanti, cumpresu un tentativu di implementà i meta-templates chì aghju digià citatu, per ùn parlà micca di analizà diverse dati da diversi siti web (in ogni modu, ùn escludu micca. chì l'arnesi di software specializati esistenti sò più adattati per questu - ùn aghju micca avutu l'experientia apprupriata di usà ancu).

A propositu, questu veranu aghju digià ricevutu un invitu per email da una sucietà chì usa tecnulugie Salesforce (u sviluppatore di l'uriginale). Gorp), passa una entrevista per u travagliu sussegwente in Riga. Sfortunatamente, per u mumentu ùn sò micca prontu per tali redistribuzioni.

Se stu materiale suscita un certu interessu, allora in a seconda parte pruvaraghju à descriverà in più dettagliu a tecnulugia per a compilazione è successivamente analizà mudelli cù l'esempiu di l'implementazione utilizata in Salesforce. Gorp (I mo aggiunte, cù l'eccezzioni di un paru di parolle di funzione digià descritte, ùn facenu praticamenti micca cambiamenti à a sintassi di u mudellu stessu, cusì quasi tutta a documentazione per u sistema originale Gorp Adatta ancu à a mo versione).

Source: www.habr.com

Add a comment