La rakonto de unu malgranda projekto dekdujara (pri BIRMA.NET unuafoje kaj sincere unuamane)

La naskiĝo de ĉi tiu projekto povas esti konsiderata malgranda ideo, kiu venis al mi ie ​​fine de 2007, kiu estis destinita trovi sian finan formon nur 12 jarojn poste (en ĉi tiu momento - kompreneble, kvankam la nuna efektivigo, laŭ al la aŭtoro, estas tre kontentiga).

Ĉio komenciĝis kiam, en la procezo de plenumi miajn tiam oficialajn devojn en la biblioteko, mi atentigis pri tio, ke la procezo de enigo de datumoj de la skanita teksto de enhavtabeloj de libro (kaj muzikaj) eldonaĵoj en la ekzistantan datumbazon, ŝajne, povas esti signife simpligita kaj aŭtomatigi, profitante la econ de ordo kaj ripeteblo de ĉiuj datumoj necesaj por enigo, kiel la nomo de la aŭtoro de la artikolo (se ni parolas pri kolekto de artikoloj), la titolo de la artikolo (aŭ la subtitolo reflektita en la enhavtabelo) kaj la paĝnumero de la nuna enhavtabelo. Komence mi estis praktike konvinkita, ke sistemo taŭga por plenumi ĉi tiun taskon facile troveblas en Interreto. Kiam ia surprizo estis kaŭzita de la fakto, ke mi ne povis trovi tian projekton, mi decidis provi efektivigi ĝin memstare.

Post sufiĉe mallonga tempo ekfunkciis la unua prototipo, kiun mi tuj komencis uzi en miaj ĉiutagaj agadoj, samtempe sencimigante ĝin sur ĉiuj ekzemploj, kiuj venis al mia mano. Feliĉe, ĉe mia kutima laborejo, kie mi tute ne estis programisto, mi tiam ankoraŭ elturniĝis kun videbla "malfunkcio" en mia laboro, dum kiu mi intense elpurigis mian ideon - preskaŭ nepensebla afero en la nunaj realaĵoj, kiuj implicas ĉiutagaj raportoj pri laboro farita dumtage. La procezo de polurado de la programo daŭris entute ne malpli ol unu jaron, sed eĉ post tio la rezulto apenaŭ povus esti nomata plene sukcesa - komence estis fiksitaj tro da diversaj konceptoj, kiuj ne estis tute klaraj por efektivigo: laŭvolaj elementoj, kiuj povas. esti preterlasita; antaŭen rigardado de elementoj (por anstataŭigi antaŭajn elementojn en serĉrezultojn); eĉ nia propra provo efektivigi ion kiel regulajn esprimojn (kiu havas unikan sintakson). Mi devas diri, ke antaŭ tio mi iom rezignis pri programado (dum ĉirkaŭ 8 jaroj, se ne pli), do tute kaptis mian atenton la nova ŝanco apliki miajn kapablojn al interesa kaj necesa tasko. Ne estas surprize, ke la rezulta fontkodo - pro manko de klaraj aliroj al sia dezajno miaflanke - sufiĉe rapide fariĝis neimagebla miksaĵo de malsimilaj pecoj en la C-lingvo kun kelkaj elementoj de C++ kaj aspektoj de vida programado (komence ĝi estis decidita uzi tian dezajnsistemon kiel Borland C++ Builder - "preskaŭ Delphi, sed en C"). Tamen ĉio ĉi finfine donis frukton en aŭtomatigo de la ĉiutagaj agadoj de nia biblioteko.

Samtempe mi decidis, ĉiaokaze, fari kursojn por trejni profesiajn programistojn. Mi ne scias, ĉu tie efektive eblas lerni “esti programisto” de nulo, sed konsiderante la kapablojn, kiujn mi jam havis tiam, mi povis iom regi teknologiojn, kiuj tiam estis pli trafaj, kiel kiel C#, Visual Studio por evoluo sub .NET, same kiel kelkaj teknologioj ligitaj al Java, HTML kaj SQL. La tuta trejnado daŭris entute du jarojn, kaj servis kiel elirpunkto por alia mia projekto, kiu finfine etendiĝis dum pluraj jaroj – sed tio estas temo por aparta eldonaĵo. Ĉi tie nur taŭgus noti, ke mi provis adapti la evoluojn, kiujn mi jam havis en la priskribita projekto, por krei plentaŭgan fenestran aplikaĵon en C# kaj WinForms, kiu efektivigas la necesan funkciecon, kaj uzi ĝin kiel bazon por la venonta diplomprojekto.
Kun la tempo, ĉi tiu ideo komencis ŝajni al mi inda esti esprimita en tiaj jaraj konferencoj kun partopreno de reprezentantoj de diversaj bibliotekoj kiel “LIBKOM” kaj “KRIMEO”. La ideo, jes, sed ne mia efektivigo de ĝi tiutempe. Tiam mi ankaŭ esperis, ke iu reverkos ĝin uzante pli kompetentajn alirojn. Iel aŭ alie, ĝis 2013 mi decidis verki raporton pri mia antaŭlaboro kaj sendi ĝin al la Konferenca Organiza Komitato kun peto por subvencio por partopreni la konferencon. Je mia iom surprizo, mia kandidatiĝo estis aprobita, kaj mi komencis fari kelkajn plibonigojn al la projekto por prepari ĝin por prezento ĉe la konferenco.

Antaŭ tiu tempo, la projekto jam ricevis novan nomon BIRMA, akiris diversajn kromajn (ne tiom plene efektivigitajn, sed prefere supozitajn) kapablojn - ĉiuj detaloj troveblas en mia raporto.

Verdire, estis malfacile nomi BIRMA 2013 io kompleta; Sincere parolante, ĝi estis tre haka metio farita en hasto. Rilate al kodo, estis preskaŭ neniuj specialaj novigoj entute, krom iom senhelpa provo krei ian unuigitan sintakson por la analizilo, en aspekto rememoriga pri la formatlingvo IRBIS 64 (kaj fakte, ankaŭ la ISIS-sistemo - kun krampoj kiel ciklaj strukturoj; kial Tiutempe mi opiniis ke ĝi aspektis sufiĉe mojosa). La analizilo senespere stumblis sur ĉi tiujn rondojn de krampoj de la taŭga tipo (ĉar krampoj ankaŭ plenumis alian rolon, nome, ili markis laŭvolajn strukturojn dum analizado, kiuj estas preterlaseblaj). Mi denove referencas ĉiujn, kiuj volas pli detale konatiĝi kun la tiam malfacile imagebla, nepravigebla sintakso de BIRMA al mia tiutempa raporto.

Ĝenerale, krom luktado kun mia propra analizilo, mi havas nenion pli por diri pri la kodo de ĉi tiu versio - krom la inversa konvertiĝo de la ekzistantaj fontoj al C++ konservante iujn tipaj trajtoj de .NET-kodo (verdire, ĝi estas malfacile komprenebla , kio ĝuste instigis min movi ĉion malantaŭen - verŝajne ia stulta timo por konservi miajn fontkodojn sekretaj, kvazaŭ ĝi estus io ekvivalenta al la sekreta recepto de Koka-kolao).

Eble ĉi tiu stulta decido troviĝas ankaŭ la kialo de la malfacilaĵoj en parigi la rezultan DLL-bibliotekon kun la ekzistanta interfaco de memfarita laborstacio por enigi datumojn en elektronikan katalogon (jes, mi ne menciis alian gravan fakton: ekde nun ĉiuj la kodo de la "motoro" BIRMA estis kiel atendite, ĝi estas apartigita de la interfaca parto kaj pakita en la taŭga DLL). Kial estis necese verki apartan laborstacion por ĉi tiuj celoj, kiu ĉiuokaze, en sia aspekto kaj metodo de interagado kun la uzanto, senhonte kopiis la saman laborstacion "Katalogizilo" de la sistemo IRBIS 64 - ĉi tio estas aparta demando. Resume: ĝi donis la necesan solidecon al miaj tiamaj evoluoj por mia diplomiĝa projekto (alie la nedigestebla analizmotoro sole iel ne sufiĉis). Krome, mi tiam renkontis kelkajn malfacilaĵojn en efektivigo de la interfaco de la kataloga laborstacio kun miaj propraj moduloj, efektivigitaj en ambaŭ C++ kaj C#, kaj rekte aliri mian motoron.

Ĝenerale, strange, estis ĉi tiu sufiĉe mallerta prototipo de la estonta BIRMA.NET, kiu estis destinita iĝi mia "laborĉevalo" dum la venontaj kvar jaroj. Oni ne povas diri, ke dum ĉi tiu tempo mi almenaŭ ne provis trovi manierojn por nova, pli kompleta realigo de longdaŭra ideo. Inter aliaj novigoj, devus esti jam nestitaj ciklaj sekvencoj, kiuj povus inkluzivi laŭvolajn elementojn - jen kiel mi vivigos la ideon de universalaj ŝablonoj por bibliografiaj priskriboj de publikaĵoj kaj diversaj aliaj interesaj aferoj. Tamen, en miaj praktikaj agadoj tiam, ĉio ĉi estis malmulte postulata, kaj la efektivigo, kiun mi tiam havis, estis sufiĉe sufiĉa por eniri enhavtabelojn. Krome, la vektoro de evoluo de nia biblioteko komencis deflankiĝi pli kaj pli al la ciferecigo de muzeaj arkivoj, raportado kaj aliaj aktivaĵoj por mi malmulte interesaj, kiuj finfine devigis min fine forlasi ĝin, cedante lokon al tiuj, kiuj volus. estu pli kontenta pri ĉio ĉi.

Paradokse, ĝuste post tiuj dramaj eventoj la projekto BIRMA, kiu tiam jam havis ĉiujn karakterizaĵojn de tipa longdaŭra konstruprojekto, ŝajnis ekhavi sian longe atenditan novan vivon! Mi havis pli da libera tempo por senutilaj pensoj, mi denove komencis kombi la Tutmondan Reton serĉante ion similan (feliĉe, nun mi jam povis konjekti serĉi ĉion ĉi ne ie ajn, sed en GitHub), kaj ie en Ĉe la komence de ĉi tiu jaro, mi finfine renkontis respondan produkton de la konata kompanio Salesforce sub la sensignifa nomo. Gorp. Per si mem, ĝi povus fari preskaŭ ĉion, kion mi bezonis de tia analiza motoro - nome, inteligente izoli individuajn fragmentojn de arbitra, sed klare strukturita teksto, dum havante sufiĉe afablan interfacon por la fina uzanto, inkluzive de tiaj kompreneblaj esencoj, kiel ŝablono, ŝablono kaj okazo, kaj samtempe uzante la konatan sintakson de regulaj esprimoj, kiu fariĝas nekompareble pli legebla pro la divido en difinitajn semantikajn grupojn por analizado.

Ĝenerale, mi decidis, ke ĉi tiu estas tiu Gorp (Mi scivolas, kion signifas ĉi tiu nomo? Eble ia "ĝenerala orientita regula analizilo"?) - ĝuste tion, kion mi serĉas delonge. Vere, ĝia tuja efektivigo por miaj propraj bezonoj havis tian problemon, ke tiu ĉi motoro postulis tro striktan sekvadon al la struktura sinsekvo de la fontteksto. Por iuj raportoj kiel protokolaj dosieroj (nome, ili estis metitaj de la programistoj kiel klaraj ekzemploj de uzado de la projekto), tio estas sufiĉe taŭga, sed por la samaj tekstoj de skanitaj enhavtabeloj, ĝi estas neverŝajna. Post ĉio, la sama paĝo kun enhavtabelo povas komenciĝi per la vortoj "Enhavo", "Enhavo" kaj iuj aliaj antaŭaj priskriboj, kiujn ni ne bezonas meti en la rezultojn de la celita analizo (kaj detranĉante ilin permane). ĉiufoje ankaŭ estas maloportuna). Krome, inter unuopaj ripetaj elementoj, kiel la nomo de la aŭtoro, titolo kaj paĝonumero, la paĝo povas enhavi certan kvanton da rubo (ekzemple desegnaĵoj, kaj nur hazardaj signoj), kiujn ankaŭ estus bone povi. fortranĉita. Tamen la lasta aspekto ankoraŭ ne estis tiom signifa, sed pro la unua, la ekzistanta efektivigo ne povis komenci serĉi la necesajn strukturojn en la teksto de certa loko, sed anstataŭe simple prilaboris ĝin ekde la komenco mem, ne trovis la precizigis ŝablonojn tie kaj... finis mian laboron. Evidente, necesas iom da tajlado por almenaŭ permesi iom da spaco inter la ripetaj strukturoj, kaj tio rekomencis min labori.

Alia problemo estis, ke la projekto mem estis efektivigita en Java, kaj se mi planis estonte efektivigi iujn rimedojn por interfacigi ĉi tiun teknologion kun konataj aplikoj por enigi datumojn en ekzistantajn datumbazojn (kiel la "Katalogo" de Irbis), tiam almenaŭ Almenaŭ faru tion en C# kaj .NET. Ne estas ke Java mem estas malbona lingvo - mi iam eĉ uzis ĝin por efektivigi interesan fenestran aplikaĵon, kiu efektivigis la funkciecon de hejma programebla kalkulilo (kadre de kursprojekto). Kaj laŭ sintakso ĝi tre similas al la sama C-diesa. Nu, ĉi tio estas nur pluso: des pli facile estos por mi fini ekzistantan projekton. Tamen, mi ne volis plonĝi denove en ĉi tiun sufiĉe nekutiman mondon de fenestroj (aŭ pli ĝuste, labortablo) Java-teknologioj - finfine, la lingvo mem ne estis "tajlorita" por tia uzo, kaj mi tute ne deziris ripeton de la antaŭa sperto. Eble estas ĝuste ĉar C# kune kun WinForms estas multe pli proksima al Delphi, kun kiu multaj el ni iam komencis. Feliĉe, la necesa solvo estis trovita sufiĉe rapide - en la formo de la projekto IKVM.NET, kiu faciligas traduki ekzistantajn Java-programojn en administritan .NET-kodon. Vere, la projekto mem jam estis forlasita de la aŭtoroj tiam, sed ĝia lasta realigo permesis al mi sufiĉe sukcese plenumi la necesajn agojn por la fonttekstoj. Gorp.

Do mi faris ĉiujn necesajn ŝanĝojn kaj kunmetis ĉion en DLL de la taŭga tipo, kiu povus facile esti "reprenita" de iuj projektoj por la .NET Framework kreita en Visual Studio. Intertempe mi kreis alian tavolon por oportuna prezento de la rezultitaj rezultoj Gorp, en la formo de respondaj datumstrukturoj, kiujn estus oportune prilabori en tabelvido (prenante kiel bazon kaj vicojn kaj kolumnojn; kaj vortarajn ŝlosilojn kaj nombrajn indeksojn). Nu, la necesaj utilecoj mem por prilabori kaj montri la rezultojn estis skribitaj sufiĉe rapide.

Ankaŭ, la procezo de adaptado de ŝablonoj por la nova motoro por instrui ĝin analizi ekzistantajn specimenojn de skanitaj tekstoj de enhavtabeloj ne kaŭzis specialajn komplikaĵojn. Fakte, mi eĉ tute ne devis referenci miajn antaŭajn ŝablonojn: mi simple kreis ĉiujn necesajn ŝablonojn de nulo. Krome, se la ŝablonoj destinitaj por labori kun la antaŭa versio de la sistemo starigas sufiĉe mallarĝan kadron por tekstoj, kiuj povus esti ĝuste analizitaj kun ilia helpo, la nova motoro jam ebligis evoluigi sufiĉe universalajn ŝablonojn taŭgajn por pluraj specoj de markado ĉe unufoje. Mi eĉ provis skribi ian ampleksan ŝablonon por iu ajn arbitra enhavtabelo teksto, kvankam, kompreneble, eĉ kun ĉiuj novaj eblecoj malfermiĝantaj al mi, inkluzive de, precipe, la limigita kapablo efektivigi la samajn nestitajn ripetantajn sinsekvojn ( kiel ekzemple familinomoj kaj inicialoj pluraj aŭtoroj en vico), tio montriĝis esti utopio.

Eble estonte eblos efektivigi certan koncepton de metaŝablonoj, kiu povos kontroli la fontan tekston por konformeco kun pluraj disponeblaj ŝablonoj samtempe, kaj poste, laŭ la rezultoj akiritaj, elekti la plej taŭga unu, uzante ian inteligentan algoritmon. Sed nun mi pli zorgis pri alia demando. Analizilo kiel Gorp, malgraŭ ĝia ĉiuflankeco kaj la modifoj kiujn mi faris, ĝi estis ankoraŭ esence nekapabla fari unu ŝajne simplan aferon, kiun mia memskribita analizilo povis fari ekde la plej unua versio. Nome: li havis la kapablon trovi kaj ĉerpi el la fontteksto ĉiujn fragmentojn, kiuj kongruas kun la masko specifita ene de la ŝablono uzata en la ĝusta loko, tute ne interesiĝante pri tio, kion enhavas la donita teksto en la spacoj inter tiuj ĉi fragmentoj. Ĝis nun, mi nur iomete plibonigis la novan motoron, permesante al ĝi serĉi ĉiujn eblajn novajn ripetojn de antaŭfiksita sinsekvo de tiaj maskoj de la nuna pozicio, lasante la eblecon por la ĉeesto en la teksto de aroj de arbitraj signoj kiuj estis tute tute. neklarigita en la analizado, enfermita inter la detektitaj ripetaj strukturoj. Tamen tio ne ebligis agordi la sekvan maskon sendepende de la rezultoj de serĉado de la antaŭa fragmento per la responda masko: la severeco de la priskribita tekststrukturo ankoraŭ ne lasis lokon por arbitraj inkludoj de neregulaj signoj.

Kaj se por la ekzemploj de enhavtabeloj, kiujn mi renkontis, ĉi tiu problemo ankoraŭ ne ŝajnis tiel serioza, tiam kiam oni provis apliki novan analizan mekanismon al simila tasko analizi la enhavon de retejo (t.e. la sama analizado), ĝi estas. limigoj estas ĉi tie ili aperis kun sia tuta evidenteco. Post ĉio, estas sufiĉe facile agordi la necesajn maskojn por fragmentoj de retmarkado, inter kiuj la datumoj, kiujn ni serĉas (kiujn devas esti eltiritaj), devus troviĝi, sed kiel ni povas devigi la analizilon tuj transiri al la sekva. simila fragmento, malgraŭ ĉiuj eblaj etikedoj kaj HTML-atributoj, kiuj povas esti metitaj en la spacojn inter ili?

Pensinte iomete, mi decidis enkonduki kelkajn servajn ŝablonojn (%all_before) и (%all_post), servante al la evidenta celo certigi, ke ĉio, kio povas esti enhavita en la fontteksto, estas preterlasita antaŭ iu ŝablono (masko) kiu sekvas ilin. Cetere, se (%all_before) simple ignoris ĉiujn ĉi arbitrajn inkludojn, do (%all_post), male, permesis aldoni ilin al la dezirata fragmento post moviĝado de la antaŭa fragmento. Ĝi sonas sufiĉe simple, sed por efektivigi ĉi tiun koncepton mi devis denove kombi tra la gorp-fontoj por fari la necesajn modifojn por ne rompi la jam efektivigitan logikon. Fine ni sukcesis fari ĉi tion (kvankam eĉ la plej unua, kvankam tre fuŝa, efektivigo de mia analizilo estis skribita, kaj eĉ pli rapide - post kelkaj semajnoj). Ekde nun la sistemo alprenis vere universalan formon - ne malpli ol 12 jarojn post la unuaj provoj funkciigi ĝin.

Kompreneble, ĉi tio ne estas la fino de niaj revoj. Vi ankaŭ povas tute reverki la gorp-ŝablonan analizilon en C#, uzante iun ajn el la disponeblaj bibliotekoj por efektivigi liberan gramatikon. Mi pensas, ke la kodo devas esti signife simpligita, kaj ĉi tio permesos al ni forigi la heredaĵon en la formo de ekzistantaj Java-fontoj. Sed kun la ekzistanta tipo de motoro, estas ankaŭ tute eble fari diversajn interesajn aferojn, inkluzive provon efektivigi la meta-ŝablonojn, kiujn mi jam menciis, sen mencii analizi diversajn datumojn de diversaj retejoj (tamen mi ne ekskludas). ke ekzistantaj fakaj programaraj iloj pli taŭgas por tio - mi simple ankoraŭ ne havis la taŭgan sperton uzi ilin).

Cetere, ĉi-somere mi jam ricevis inviton retpoŝte de kompanio, kiu uzas Salesforce-teknologiojn (la programisto de la originala Gorp), pasigi intervjuon por posta laboro en Rigo. Bedaŭrinde, nuntempe mi ne estas preta por tiaj redeplojoj.

Se ĉi tiu materialo vekas iom da intereso, tiam en la dua parto mi provos priskribi pli detale la teknologion por kompili kaj poste analizi ŝablonojn uzante la ekzemplon de la efektivigo uzata en Salesforce. Gorp (miaj propraj aldonoj, escepte de kelkaj jam priskribitaj funkciovortoj, praktike ne faras ŝanĝojn al la ŝablona sintakso mem, do preskaŭ la tuta dokumentaro por la originala sistemo Gorp Taŭga ankaŭ por mia versio).

fonto: www.habr.com

Aldoni komenton