Ekspresi reguler + pemrograman logis. Apa hasilnya?

Halo pembaca yang budiman.

Ekspresi reguler adalah hal yang terkenal yang digunakan dalam berbagai proyek, paling sering untuk kasus parsing teks terstruktur yang tidak terlalu rumit. Pada pandangan pertama, terlibat dalam tugas yang sedikit berbeda seperti sintesis terbalik dari model program (ketika ada kode program yang secara otomatis dihasilkan oleh beberapa sistem sesuai dengan beberapa model blok masalah yang sedang dipecahkan, dan perlu untuk membuat kembali model asli menggunakan kode ini), serta mensintesis model program menggunakan teks deskripsi tugas, saya mengalami masalah menganalisis teks, atau lebih tepatnya, mengidentifikasi fragmen teks ke beberapa templat kustom. Saya ingin mendapatkan solusi yang cukup sederhana dan fleksibel (dapat disesuaikan). Ekspresi reguler, on the fly, tampaknya tidak begitu, karena walaupun dalam tugas yang sederhana seperti memeriksa kata dalam kamus, sayangnya, diperlukan daftar yang cermat dari semua opsi dalam ekspresi ini. Dan mereka tidak membangun pohon parse. Namun, mereka jelas dapat ditingkatkan. Ini akan dibahas.

Jadi, tugas - tugas berikut telah ditetapkan:

  1. Ekspresi reguler harus dapat menghasilkan pohon parsing. Diperlukan untuk mengimplementasikan sarana standar akses ke pohon ini.
  2. Ekspresi reguler harus dapat menyertakan pemeriksaan pada fragmen yang ditemukan dalam kamus (korespondensi yang tepat atau tidak ketat menurut Levenshtein), serta pemeriksaan yang lebih kompleks pada beberapa tabel pada saat yang bersamaan.
  3. Selain cek sederhana (tercantum di atas), saya ingin memiliki lebih banyak cek fuzzy, misalnya, kompatibilitas kata dan ekspresi, jaringan saraf

Parse tree.


Dalam ekspresi reguler, fragmen yang diurai diidentifikasi oleh jumlah tanda kurung. Ini, secara sederhana, tidak nyaman, sehingga keputusan dibuat tentang kemungkinan penamaan kurung. Ngomong-ngomong, nama-nama inilah yang seharusnya muncul di pohon parsing. Sintaks dipilih sederhana:

(_)->{_} 

Jika setelah tanda kurung dalam ekspresi asli ada operator (*, +, dll.), Maka dia "bergerak" di belakang kurung kurawal kanan. Sebagai contoh:

 (\w+\s)->{A}+ 

Tidak ada yang mencegah penamaan dan tanda kurung, misalnya:

 ((\w+)->{ID}\s)->{A}+ 

Dalam contoh terakhir, ekspresi reguler yang dimodifikasi akan menghasilkan parsing tree dengan beberapa root kondisional, pada tingkat berikutnya ada contoh A (mungkin ada lebih dari satu), pada tingkat berikutnya ada nilai ID. Lebih mudah untuk mengakses pohon seperti itu menggunakan XPath, yang telah saya terapkan, misalnya, permintaan seperti itu mungkin:

 //A[2]/ID[text()!=""]/text() 

Word memeriksa kamus, tabel, dan jaringan saraf sederhana


Mem-parsing ekspresi reguler sangat mirip dengan parsing ekspresi logis sederhana, misalnya, dalam bahasa Prolog. Ini mengarah pada gagasan bahwa Prolog seperti fragmen, yaitu:

a) rantai berbagai pemeriksaan. Ini tidak sulit, terutama karena variabel sudah muncul (dalam bentuk kurung bernama);
b) atau penambahan tabel / kamus dengan fragmen yang terdeteksi;
c) atau pengecualian dari tabel / kamus dari fragmen yang terdeteksi;
d) atau tim pelatihan / penciptaan jaringan saraf.

Sintaks umum di sini adalah:

 (_)_=>{1,2,...} 

operation_symbol tergantung pada operasi: verifikasi (?), pengisian (+), pengecualian (-), pembuatan / pelatihan (*). Adapun predikat, nama predikat (standar atau Anda sendiri) dan daftar parameter dalam tanda kurung ditunjukkan. Parameter dapat berupa konstanta, variabel input, variabel output (diawali dengan tanda "$"), tanda nilai sewenang-wenang "_", referensi ke nilai saat ini dari fragmen ekspresi_ (karakter tunggal "$"). Analisis ungkapan semacam itu dianggap berhasil jika semua predikat dalam rantai berhasil.

Misalnya, ungkapan:

 ([--]+)->{V1}\s+([--]+)->{V2}()?=>{check(V1},check(V2),correlate(V1,V2)} 

memilih dua kata berturut-turut dalam bahasa Rusia dan menempatkannya dalam variabel V1 dan V2, dan kemudian memeriksa kata-kata ini dengan cek predikat (ini bisa berupa pemeriksaan sederhana di atas tabel) dan, sebagai kesimpulan, dengan predikat berkorelasi (bisa juga ada cek di atas meja). Jenis verifikasi (ketat atau tidak ketat) ditentukan oleh spesifikasi predikat.

Jika tabel berkorelasi tidak mengandung kata-kata itu sendiri, tetapi beberapa kode kata dan karakteristik kompatibilitasnya, maka mungkin ada ungkapan seperti itu:

 ()->{C1}()->{C2}([--]+)->{check($,$C1}\s+([--]+)->{V2}()?=>{check(V2,$C2),correlate(C1,C2,1)} 

Di sini, dua variabel pertama kali diperkenalkan, C1 dan C2. Predikat yang berkorelasi juga dapat berupa jaringan saraf dengan dua input (kode kata) dan satu output (kompatibilitas), yang dilatih menurut beberapa set yang telah ditentukan atau secara dinamis dirakit (selama operasi ekspresi reguler).

Masih menambahkan bahwa arahan khusus paralel dan berurutan juga dapat ditentukan sebagai predikat, yang masing-masing, termasuk dan menghitung paralelisme eksekusi dalam rantai predikat (yang dikonversi ke pohon dependensi predikat, sesuai dengan yang diparalelkan). Selain itu, Anda dapat mengaktifkan mode khusus di mana upaya dilakukan untuk secara dinamis memprediksi waktu eksekusi masing-masing predikat dan memutuskan apakah concurrency akan efektif, atau sebaliknya, hanya akan membawa biaya tambahan.

Kesimpulan


Semua modifikasi ekspresi reguler yang dijelaskan diimplementasikan dalam prototipe (modifikasi regexpr.pas standar) pada Free Pascal.

Saya harap ide-ide ini bermanfaat bagi seseorang.

Sekarang, dengan menggunakan ekspresi logis reguler + pemrograman pada Prolog murni, adalah mungkin, pertama, untuk menulis add-on ke sistem pembuatan program yang mengembalikan model program asli dari kode yang sebelumnya dibuat olehnya, dan kedua, untuk membuat elemen-elemen bahasa alami untuk sistem ini. antarmuka (pernyataan masalah diadopsi dalam bahasa Rusia yang sangat sederhana dan model masalah dirumuskan di atasnya, sesuai dengan yang program ini sudah dihasilkan).

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


All Articles