Pendeknya
Tampaknya solusi cepat untuk masalah Anda adalah menentukan REGEX, atau FSA (finite state automaton), yang mengenali semua kemungkinan awal dokumen (positif palsu diizinkan, yang tidak akan benar-benar sesuai dengan dokumen). Anda kemudian dapat menjalankannya dengan sangat cepat pada input Anda untuk mengidentifikasi tempat berikutnya di mana dokumen dapat dimulai dengan beberapa kesalahan. Ini dapat menyebabkan beberapa posisi yang salah untuk memulai dokumen, tetapi mereka akan dikenali oleh pengurai dan ditinggalkan.
Jadi Finite State Automaton mungkin adalah nama pengurai yang Anda cari. :)
Masalah
Selalu sulit untuk memahami masalah praktis, terutama ketika kosa kata mungkin memiliki banyak interpretasi. Kata parse forest dibuat (afaik) untuk parsing Context-Free (CF) dari kalimat-kalimat ambigu yang memiliki beberapa pohon parse. Ini dapat digeneralisasi agak untuk mengurai kisi kalimat, atau jenis tata bahasa lainnya. Karenanya semua jawaban tentang Earley, GLR, Marpa dan parser turunan (ada banyak lainnya) yang tidak relevan dalam kasus ini.
Tapi itu rupanya bukan yang Anda pikirkan. Anda ingin mengurai string unik yang merupakan urutan dokumen yang tidak ambigu, dan mendapatkan parse-tree untuk masing-masing , atau semacam representasi terstruktur, karena Anda tidak benar-benar mengatakan bagaimana sintaks dokumen Anda didefinisikan, di mana ia berdiri dari sudut pandang bahasa formal. Apa yang Anda miliki adalah algoritma dan tabel yang akan melakukan pekerjaan parsing ketika dimulai pada awal dokumen. Jadilah itu.
Masalah sebenarnya adalah aliran dokumen Anda mengandung banyak sampah yang memisahkan dokumen. Dan tampaknya kesulitan Anda untuk memindai sampah ini cukup cepat. Teknik Anda saat ini adalah mulai dari awal, dan mencoba memindai dari karakter pertama, dan lewati untuk memulai kembali di karakter berikutnya setiap kali gagal, sampai Anda mendapatkan seluruh dokumen dipindai. Kemudian Anda ulangi pernyataan dari karakter pertama setelah dokumen dipindai.
Itu juga solusi yang disarankan oleh @amon di bagian kedua dari jawabannya .
Ini mungkin bukan solusi yang sangat cepat (saya tidak punya cara untuk menguji), karena tidak mungkin kode parser dioptimalkan menjadi sangat efisien dimulai pada awal dokumen. Dalam penggunaan normal, ia melakukan ini hanya sekali, sehingga ini bukan hot spot dari sudut pandang optimasi. Karenanya, kebahagiaan Anda yang moderat dengan solusi ini tidak terlalu mengejutkan.
Jadi yang Anda butuhkan adalah algoritma yang dapat dengan cepat menemukan awal dokumen yang dimulai dengan banyak sampah. Dan Anda beruntung: algoritma seperti itu memang ada. Dan saya yakin Anda tahu itu: itu disebut mencari REGEX.
Solusi sederhana
Yang harus Anda lakukan adalah menganalisis spesifikasi dokumen Anda untuk menemukan bagaimana dokumen ini dimulai. Saya tidak bisa memberi tahu Anda dengan pasti bagaimana, karena saya tidak yakin bagaimana spesifikasi sintaksisnya diatur secara formal. Mungkin mereka semua mulai dengan beberapa kata dari daftar yang terbatas, mungkin dicampur dengan beberapa tanda baca atau angka. Itu untuk Anda periksa.
Apa yang harus Anda lakukan adalah mendefinisikan otomat keadaan terbatas (FSA), atau setara dengan kebanyakan programmer ekspresi reguler (REGEX) yang dapat mengenali beberapa karakter pertama dokumen: semakin banyak, semakin baik, tetapi tidak harus sangat besar (karena itu mungkin membutuhkan waktu dan ruang). Ini harus relatif mudah dilakukan dari spesifikasi dokumen Anda, dan mungkin dapat dilakukan secara otomatis dengan program yang membaca spesifikasi dokumen Anda.
Setelah Anda menghasilkan regexp Anda, Anda dapat menjalankannya pada aliran input Anda untuk menjadi sangat cepat ke awal dokumen pertama (atau selanjutnya) Anda sebagai berikut:
Saya berasumsi:
- docstart
adalah regex yang cocok dengan awal semua dokumen
- search(regex, stream)
adalah fungsi yang mencari stream
substring yang cocok regex
. Ketika kembali, aliran direduksi menjadi subfiks sufiks mulai dari awal substring pencocokan pertama, atau ke aliran kosong tidak ditemukan kecocokan.
- parse(stream)
mencoba mengurai dokumen dari awal aliran (apa yang tersisa dari itu), dan mengembalikan pohon pengurai dalam format apa pun, atau gagal. Ketika kembali, aliran dikurangi ke subtream suffix-nya mulai dari posisi segera setelah akhir dokumen yang diuraikan. Ini memanggil pengecualian jika parse gagal.
forest = empty_forest
search(docstart, stream)
while stream is not empty:
try:
forest = forest + parse(stream)
except
remove first character from stream
search(docstart, stream)
Perhatikan bahwa penghapusan karakter pertama diperlukan agar pencarian berikutnya tidak menemukan lagi kecocokan yang sama.
Tentu saja, pemendekan aliran adalah gambar. Mungkin hanya indeks di sungai.
Catatan terakhir adalah bahwa regex Anda tidak perlu terlalu akurat, asalkan itu mengenali semua awal. Jika kadang-kadang mengenali string yang tidak bisa menjadi awal dokumen (false positive), maka satu-satunya hukuman adalah biaya satu panggilan tidak berguna ke parser.
Sehingga mungkin dapat membantu menyederhanakan regex, jika berguna.
Tentang kemungkinan solusi yang lebih cepat
Solusi di atas harus bekerja dengan cukup baik dalam banyak kasus. Namun, jika Anda benar-benar memiliki banyak file sampah dan terabyte untuk diproses, mungkin ada algoritma lain yang berjalan lebih cepat.
Idenya berasal dari algoritma pencarian string Boyer-Moore . Algoritma ini dapat mencari aliran untuk string tunggal dengan sangat cepat karena menggunakan analisis struktural dari string untuk melewatkan membaca sebagian besar aliran, melompati fragmen tanpa melihatnya. Ini adalah algoritma pencarian tercepat untuk satu string.
Kesulitannya adalah bahwa adaptasinya untuk mencari regex, daripada string tunggal, tampaknya sangat halus dan mungkin tidak berfungsi juga, tergantung pada fitur regex yang Anda pertimbangkan. Yang pada gilirannya mungkin tergantung pada sintaks dokumen yang Anda parsing. Tetapi jangan terlalu mempercayai saya tentang hal ini karena saya tidak punya waktu untuk membaca dokumen-dokumen yang saya temukan dengan cermat.
Saya meninggalkan Anda dengan satu atau dua petunjuk yang saya temukan di web, termasuk satu yang kelihatannya merupakan makalah penelitian wasit , tetapi Anda harus menganggap ini sebagai lebih spekulatif, mungkin penelitian, untuk dipertimbangkan hanya jika Anda memiliki masalah kinerja yang kuat. Dan mungkin tidak ada program rak yang akan melakukannya.