Sejarah satu proyek kecil yang panjangnya dua belas tahun (tentang BIRMA.NET untuk pertama kalinya dan jujur ​​langsung)

Kelahiran proyek ini dapat dianggap sebagai gagasan kecil yang mengunjungi saya di suatu tempat pada akhir 2007, yang ditakdirkan untuk menemukan bentuk akhirnya hanya 12 tahun kemudian (pada titik waktu ini - tentu saja, meskipun implementasi saat ini, menurut pendapat penulis, sangat memuaskan) .

Semuanya dimulai dengan fakta bahwa dalam proses memenuhi tugas resmi saya di perpustakaan, saya menarik perhatian pada fakta bahwa proses memasukkan data dari teks yang dipindai dari daftar isi buku (dan musik) publikasi ke dalam database yang ada, tampaknya, dapat sangat disederhanakan. dan mengotomatisasi, menggunakan properti keteraturan dan pengulangan semua data yang diperlukan untuk input, seperti nama penulis artikel (jika kita berbicara tentang kumpulan artikel), nama artikel (atau subtitle yang tercermin dalam daftar isi) dan Halaman daftar isi saat ini. Pada awalnya, saya hampir yakin bahwa sistem yang cocok untuk tugas ini dapat dengan mudah ditemukan di Internet. Ketika beberapa kejutan disebabkan oleh fakta bahwa saya tidak dapat menemukan proyek seperti itu, saya memutuskan untuk mencoba mengimplementasikannya sendiri.

Setelah waktu yang cukup singkat, prototipe pertama mulai bekerja, yang segera saya mulai gunakan dalam kegiatan sehari-hari, secara bersamaan men-debug-nya dengan semua contoh yang ada di tangan saya. Untungnya, di tempat kerja saya yang biasa, di mana saya sama sekali bukan programmer, saya masih bisa lolos dengan "downtime" yang terlihat dalam pekerjaan, di mana saya bekerja keras untuk men-debug gagasan saya - hal yang hampir tidak terpikirkan dalam kenyataan hari ini, menyiratkan laporan harian tentang pekerjaan dilakukan pada siang hari. Proses memoles program membutuhkan total tidak kurang dari setahun, tetapi bahkan setelah itu hasilnya hampir tidak dapat disebut sepenuhnya berhasil - ada terlalu banyak konsep yang berbeda yang tidak cukup dapat diimplementasikan dari awal: elemen opsional yang dapat dilewati; tampilan terkemuka elemen (untuk tujuan menggantikan hasil pencarian elemen sebelumnya); bahkan usaha Anda sendiri untuk mengimplementasikan sesuatu seperti ekspresi reguler (memiliki sintaks yang berbeda). Saya harus mengatakan bahwa sebelumnya saya berhasil melempar pemrograman sedikit (selama sekitar 8 tahun, jika tidak lebih), jadi kesempatan baru untuk menerapkan keterampilan saya pada tugas yang menarik dan perlu benar-benar menarik perhatian saya. Tidak mengherankan bahwa kode sumber yang dihasilkan - dengan tidak adanya pendekatan yang dapat dipahami untuk mendesainnya bagi saya - dengan cepat menjadi suatu mishmash potongan-potongan yang berbeda dalam bahasa C dengan beberapa elemen C ++ dan aspek pemrograman visual (pada awalnya diputuskan untuk menggunakan sistem desain seperti Borland C ++ Builder - "hampir Delphi, tetapi dalam C"). Namun, semua ini akhirnya terbayar dalam otomatisasi kegiatan sehari-hari perpustakaan kami.

Pada saat yang sama, saya memutuskan, untuk berjaga-jaga, untuk mengambil kursus pelatihan untuk pengembang perangkat lunak profesional. Saya tidak tahu apakah mungkin untuk benar-benar belajar "dari seorang programmer" dari awal, tetapi dengan mempertimbangkan keterampilan yang sudah saya miliki pada saat itu, saya dapat menguasai sedikit teknologi yang lebih maju seperti C #, Visual Studio untuk dikembangkan di bawah. NET, serta beberapa teknologi yang terkait dengan Java, HTML dan SQL. Semua pelatihan berlangsung selama dua tahun, dan menjadi titik awal untuk proyek saya yang lain, yang akhirnya membentang selama beberapa tahun - tetapi ini sudah menjadi topik untuk publikasi yang terpisah. Di sini hanya akan relevan untuk dicatat bahwa saya membuat upaya untuk menyesuaikan pengalaman yang sudah saya miliki pada proyek yang dijelaskan untuk membuat aplikasi jendela lengkap di C # dan WinForms yang mengimplementasikan fungsionalitas yang diperlukan, dan meletakkannya di dasar proyek kelulusan yang akan datang.
Seiring waktu, ide ini mulai tampak layak disuarakan pada konferensi tahunan tersebut dengan partisipasi perwakilan dari berbagai perpustakaan, seperti LIBCOM dan CRIMEA. Idenya adalah ya, tetapi tidak berarti realisasi saya saat itu. Kemudian saya juga berharap, antara lain, bahwa seseorang akan menulis ulang menggunakan pendekatan yang lebih kompeten. Dengan satu atau lain cara, pada tahun 2013, saya memutuskan untuk menyusun laporan tentang pekerjaan pendahuluan saya dan mengirimkannya ke Komite Penyelenggara Konferensi dengan permohonan hibah untuk berpartisipasi dalam konferensi. Yang mengejutkan saya, aplikasi saya puas, dan saya mulai membuat beberapa perbaikan pada proyek untuk mempersiapkannya untuk presentasi di konferensi.

Pada saat itu, proyek telah menerima nama baru BIRMA, memperoleh berbagai peluang tambahan (tidak begitu terwujud sepenuhnya seperti yang diharapkan) - semua detail dapat ditemukan dalam laporan saya .

Terus terang, BIRMA 2013 sulit untuk menyebut sesuatu yang lengkap; sejujurnya, itu adalah cambuk yang dibuat dengan sangat rumit. Adapun bagian kode, praktis tidak ada inovasi khusus sama sekali, selain dari upaya yang agak tak berdaya untuk membuat semacam sintaks terpadu untuk parser, yang dalam penampilannya menyerupai bahasa format IRBIS 64 (dan, bahkan, ISIS, dengan tanda kurung dalam peran struktur siklik; mengapa maka menurut saya itu terlihat sangat keren). Parser dengan putus asa menemukan pusaran air dari kurung dari tipe yang sesuai (karena kurung memainkan peran yang sama di sana, yaitu, mereka menandai struktur opsional yang dapat dilewati selama parsing). Setiap orang yang ingin berkenalan secara lebih terperinci dengan sintaks BIRMA yang sulit dibayangkan, tidak dapat dibenarkan, saya kembali merujuk pada laporan saya saat itu.

Secara umum, kecuali untuk perjuangan dengan parser kita sendiri, maka sejauh menyangkut kode versi ini, saya tidak ada lagi yang perlu dikatakan - kecuali untuk konversi terbalik dari sumber yang tersedia di C ++ dengan pelestarian beberapa fitur khas dari kode .NET (jujur, sulit untuk dimengerti apa sebenarnya yang mendorong saya untuk mentransfer semuanya kembali - mungkin semacam ketakutan aneh untuk merahasiakan kode sumber saya, seolah-olah itu setara dengan resep rahasia Coca-Cola).

Mungkin keputusan bodoh ini juga berisi alasan kesulitan dalam memasangkan DLL yang dihasilkan dengan antarmuka workstation buatan sendiri yang ada untuk memasukkan data ke dalam katalog elektronik (ya, saya tidak menyebutkan satu lagi fakta penting: mulai sekarang semua kode mesin BIRMA adalah seperti yang diharapkan, dipisahkan dari antarmuka dan dikemas dalam DLL yang sesuai). Mengapa Anda perlu menulis workstation terpisah untuk keperluan ini, yang bagaimanapun, dalam penampilan dan cara berinteraksi dengan pengguna, tanpa malu-malu menyalin workstation "Catalogizer" yang sama dari sistem IRBIS 64 - ini adalah masalah yang terpisah. Singkatnya: ia memberi hormat kepada pencapaian saya saat itu untuk proyek kelulusan (jika tidak mesin pengurai yang dicerna sendiri entah bagaimana tidak cukup). Selain itu, saya kemudian menemui beberapa kesulitan ketika menerapkan pemasangan workstation "Catalogizer" dengan modul saya sendiri yang diimplementasikan baik dalam C ++ dan C #, dan menangani langsung ke mesin saya.

Secara umum, cukup aneh, tetapi prototipe BIRMA.NET masa depan yang agak canggung inilah yang ditakdirkan untuk menjadi "pekerja keras" saya selama empat tahun ke depan. Tidak dapat dikatakan bahwa selama ini saya bahkan tidak mencoba menemukan cara untuk implementasi baru yang lebih lengkap dari ide lama. Di antara inovasi lain seharusnya sudah ada urutan siklik bersarang, yang dapat mencakup elemen opsional juga - itulah bagaimana saya akan mewujudkan gagasan template universal untuk deskripsi publikasi publikasi bibliografi dan berbagai hal menarik lainnya. Namun, dalam praktik saya pada waktu itu, semua ini tidak dituntut, dan implementasi yang saya miliki saat itu cukup untuk memperkenalkan daftar isi. Selain itu, vektor arah pengembangan perpustakaan kami mulai semakin menyimpang ke arah digitalisasi arsip museum, menghasilkan laporan dan kegiatan lain yang kurang menarik bagi saya, yang pada akhirnya membuat saya meninggalkannya sepenuhnya, memberi jalan bagi mereka yang akan lebih senang dengan semua ini .

Paradoksnya, tetapi tepat setelah peristiwa dramatis ini, proyek BIRMA, yang pada saat itu sudah memiliki semua ciri khas dari konstruksi jangka panjang yang khas, tampaknya mulai mendapatkan kehidupan barunya yang telah lama ditunggu-tunggu! Saya memiliki lebih banyak waktu luang untuk pikiran-pikiran yang tidak berguna, saya mulai lagi menjelajahi World Wide Web untuk mencari sesuatu yang serupa (bagus, sekarang saya sudah bisa menebak untuk mencari semua ini dari mana saja, yaitu di GitHub), dan di suatu tempat di Pada awal tahun ini, saya akhirnya menemukan kerajinan yang sesuai dari kantor Salesforce yang terkenal dengan nama Gorp yang tidak penting. Dengan sendirinya, itu bisa melakukan hampir semua yang saya butuhkan dari mesin parser seperti - yaitu, secara cerdas mengisolasi fragmen individu dari sewenang-wenang, tetapi dengan struktur teks yang jelas, sementara memiliki antarmuka yang cukup mudah dicerna untuk pengguna akhir, termasuk yang jelas entitas sebagai pola, pola, dan kejadian, dan pada saat yang sama melibatkan sintaksis biasa dari ekspresi reguler, yang menjadi jauh lebih mudah dibaca dengan memecah menjadi kelompok semantik yang bermakna untuk dianalisis.

Secara umum, saya memutuskan bahwa Gorp yang sama ini (saya ingin tahu apa arti nama ini? Mungkin beberapa "parser reguler yang berorientasi umum"?) Apakah persis apa yang telah saya cari sejak lama. Benar, implementasi langsungnya untuk kebutuhan saya sendiri memiliki masalah sehingga mesin ini membutuhkan kepatuhan yang terlalu ketat terhadap urutan struktural teks sumber. Untuk beberapa laporan seperti file log (yaitu, mereka ditempatkan oleh pengembang sebagai contoh visual dari penggunaan proyek), ini akan berfungsi dengan baik, tetapi untuk teks yang sama daftar isi yang dipindai tidak mungkin. Lagipula, halaman yang sama dengan daftar isi dapat dimulai dengan kata-kata “Daftar Isi”, “Daftar Isi” dan beberapa deskripsi awal lainnya yang sama sekali tidak kita perlukan untuk ditempatkan dalam hasil analisis yang diusulkan (dan juga tidak nyaman untuk memotongnya secara manual setiap kali). Selain itu, di antara elemen berulang, seperti nama penulis, judul, dan nomor halaman, halaman tersebut mungkin mengandung sejumlah sampah tertentu (misalnya, gambar, dan hanya karakter acak), yang juga baik untuk dapat dipotong. Namun, aspek terakhir masih tidak begitu signifikan, tetapi berdasarkan yang pertama, implementasi yang ada tidak dapat mulai mencari struktur yang diperlukan dalam teks dari beberapa tempat tertentu, tetapi alih-alih hanya memprosesnya dari awal, tidak menemukan pola yang ditentukan di sana dan ... selesai pekerjaanmu Jelas, diperlukan revisi yang tepat, yang akan memungkinkan setidaknya meninggalkan beberapa celah di antara struktur yang berulang, dan ini membuat saya duduk lagi di tempat kerja.

Masalah lain adalah bahwa proyek itu sendiri diimplementasikan di Jawa, dan jika saya berencana untuk lebih lanjut mengimplementasikan beberapa cara untuk menghubungkan teknologi ini dengan aplikasi biasa untuk memasukkan data ke dalam basis data yang ada (seperti kataloger Irbis), maka setidaknya Setidaknya lakukan di C # dan .NET. Bukan berarti Java itu sendiri adalah bahasa yang buruk - bahkan ketika saya mengimplementasikannya pada aplikasi jendela yang tidak menarik yang mengimplementasikan fungsi dari kalkulator yang dapat diprogram dalam negeri (sebagai bagian dari proyek kursus). Ya, dan dalam sintaksisnya sangat mirip dengan C-sharpe yang sama. Nah, ini hanya nilai tambah: semakin mudah bagi saya untuk menyelesaikan proyek yang sudah ada. Namun, saya tidak ingin terjun ke dunia teknologi Java yang agak tidak biasa ini (atau lebih tepatnya desktop) - pada akhirnya, bahasa itu sendiri tidak "diasah" untuk penggunaan seperti itu, dan saya sama sekali tidak lama mengulangi pengalaman sebelumnya. Mungkin itu karena C # dalam hubungannya dengan WinForms jauh lebih dekat dengan Delphi, yang banyak dari kita pernah mulai. Untungnya, solusi yang tepat ditemukan cukup cepat - dalam pribadi proyek IKVM.NET , yang membuatnya mudah untuk menerjemahkan program Java yang ada ke dalam kode .NET yang dikelola. Benar, proyek itu sendiri sudah ditinggalkan oleh penulis pada waktu itu, tetapi implementasi terbarunya memungkinkan saya untuk cukup berhasil melakukan tindakan yang diperlukan untuk teks sumber Gorp .

Jadi saya membuat semua perubahan yang diperlukan dan memasukkan semuanya ke dalam DLL dari jenis yang sesuai, yang mana proyek untuk .NET Framework dibuat di Visual Studio dapat dengan mudah "mengambil". Sementara itu , saya membuat layer lain untuk presentasi yang mudah dari hasil yang dikembalikan oleh Gorp , dalam bentuk struktur data yang sesuai yang akan nyaman untuk diproses dalam representasi tabel (dan mengambil sebagai dasar baik baris dan kolom; baik kunci kamus dan indeks numerik) . Nah, utilitas yang diperlukan sendiri untuk memproses dan menampilkan hasilnya ditulis cukup cepat.

Juga, proses mengadaptasi templat untuk mesin baru tidak menyebabkan komplikasi khusus untuk mengajarinya cara membongkar sampel yang ada dari teks daftar isi yang dipindai. Bahkan, saya bahkan tidak perlu membuka tempat kosong sebelumnya: Saya baru saja membuat semua templat yang diperlukan dari awal. Selain itu, jika templat yang dirancang untuk bekerja dengan versi sistem sebelumnya menetapkan kerangka kerja yang cukup sempit untuk teks yang dapat diurai dengan benar dengan bantuan mereka, mesin baru telah memungkinkan pengembangan templat yang cukup universal yang cocok untuk beberapa jenis markup sekaligus. Saya bahkan mencoba untuk menulis beberapa templat komprehensif untuk sembarang daftar isi teks, walaupun, tentu saja, bahkan dengan semua kemungkinan baru yang terbuka bagi saya, termasuk, khususnya, kemampuan terbatas untuk menerapkan semua urutan berulang berulang bersarang (seperti, misalnya, nama belakang dan inisial beberapa penulis berturut-turut), ini ternyata sebuah utopia.

Ada kemungkinan bahwa di masa mendatang akan dimungkinkan untuk menerapkan konsep meta-templat tertentu yang dapat memeriksa teks sumber untuk kepatuhan dengan beberapa templat yang tersedia sekaligus, dan kemudian, sesuai dengan hasil yang diperoleh, pilih yang paling cocok menggunakan beberapa algoritma cerdas. Tetapi sekarang saya lebih khawatir tentang pertanyaan lain. Pengurai seperti Gorp , terlepas dari segala keserbagunaan dan modifikasinya yang dibuat oleh saya, masih pada dasarnya tidak mampu melakukan satu hal yang tampaknya sederhana yang dapat dilakukan oleh pengurai tulisan tangan saya sendiri dari versi pertama. Yaitu: ia memiliki kemampuan untuk menemukan dan mengekstrak dari teks sumber semua fragmen yang cocok dengan topeng yang ditentukan dalam kerangka templat yang digunakan di tempat yang tepat, sementara sama sekali tidak tertarik pada apa yang teks isikan dalam ruang di antara fragmen-fragmen ini. Sejauh ini, saya hanya sedikit memperbaiki mesin baru, memungkinkannya untuk mencari semua kemungkinan pengulangan baru dari urutan tertentu dari topeng seperti itu dari posisi saat ini, meninggalkan kemungkinan teks akan sepenuhnya diabaikan ketika parsing set karakter sewenang-wenang tertutup di antara struktur berulang yang terdeteksi. Namun, ini tidak memungkinkan untuk menetapkan mask berikutnya terlepas dari hasil pencarian untuk fragmen sebelumnya oleh mask yang sesuai dengannya: ketatnya struktur teks yang dijelaskan masih tidak memberikan ruang untuk penyertaan sewenang-wenang dari karakter tidak beraturan.

Dan jika untuk contoh daftar isi yang saya temui masalah ini tampaknya belum begitu serius, maka ketika mencoba menerapkan mekanisme parsing baru pada tugas yang sama pada dasarnya untuk mem-parsing konten situs web (mis. Parsing yang sama), batasannya ada di sini mereka muncul dengan semua bukti mereka. Lagipula, cukup sederhana untuk mengatur topeng yang diperlukan untuk fragmen markup web, di antaranya adalah data yang kita cari (yang perlu Anda ekstrak), tetapi bagaimana membuat parser segera menuju ke fragmen serupa berikutnya, terlepas dari semua kemungkinan tag HTML dan atribut yang dapat ditampung kesenjangan di antara mereka?

Setelah sedikit berpikir, saya memutuskan untuk memperkenalkan beberapa pola utilitas (% all_before) dan (% all_after) , yang melayani tujuan yang jelas untuk memastikan penghapusan segala sesuatu yang dapat terkandung dalam teks sumber sebelum pola berikutnya (topeng). Selain itu, jika (% all_before) mengabaikan semua inklusi sewenang-wenang ini, maka (% all_after) , sebaliknya, memperbolehkannya ditambahkan ke fragmen yang diinginkan setelah beralih dari fragmen sebelumnya. Kedengarannya cukup sederhana, tetapi untuk mengimplementasikan konsep ini, saya harus "menyisir" sumber gorp lagi untuk membuat modifikasi yang diperlukan agar tidak merusak logika yang sudah diterapkan. Pada akhirnya, saya berhasil melakukannya (meskipun implementasi parser parser saya yang sangat, sangat pertama, meskipun sangat buggy telah ditulis dan bahkan lebih cepat - dalam beberapa minggu).Mulai sekarang, sistem telah mengambil bentuk yang benar-benar universal - tidak kurang dari 12 tahun setelah upaya pertama untuk membuatnya berfungsi.

Tentu saja, ini bukan impian utama. Anda masih dapat sepenuhnya menulis ulang parser templat gorp di C # menggunakan pustaka yang tersedia untuk menerapkan tata bahasa gratis. Saya pikir kode itu harus sangat disederhanakan, dan ini akan menghilangkan warisan dalam bentuk sumber yang ada di Jawa. Tetapi dengan mesin yang ada, sangat mungkin untuk melakukan berbagai hal menarik, termasuk upaya untuk mengimplementasikan meta-templat yang telah saya sebutkan, belum lagi mem-parsing berbagai data dari berbagai situs web (namun, saya tidak mengecualikan bahwa alat perangkat lunak khusus yang ada lebih cocok untuk ini - Saya hanya tidak memiliki pengalaman yang relevan dalam menggunakannya).

Ngomong-ngomong, musim panas ini saya sudah menerima undangan email dari perusahaan yang menggunakan teknologi Salesforce (pengembang Gorp asli ) untuk lulus wawancara untuk pekerjaan lebih lanjut di Riga. Sayangnya, saat ini saya belum siap untuk pindah.

Bagian kedua menjelaskan secara lebih rinci teknologi untuk mengkompilasi dan kemudian mem -parsing templat menggunakan contoh implementasi yang digunakan dalam Salesforce Gorp (tambahan saya sendiri, dengan pengecualian beberapa kata layanan yang sudah dijelaskan, praktis tidak mengubah sintaks templat itu sendiri, sehingga hampir semua dokumentasi untuk sistem asli GorpCocok untuk versi saya). Di sana Anda akan menemukan kode sampel untuk berinteraksi dengan mesin ini dan tautan ke repositori versi saya - Gorp.NET .

Source: https://habr.com/ru/post/id474536/


All Articles