İkili verilerde bir lexer / ayrıştırıcı kullanmak neden bu kadar yanlış?


13

Bir ayrıştırıcı birleştiricinin aksine lexer / ayrıştırıcılarla sık sık çalışıyorum ve ayrıştırmada hiç ders almayan insanları görüyorum, ikili verileri ayrıştırmayı sor. Tipik olarak veriler sadece ikili değil aynı zamanda içeriğe duyarlıdır. Bu temel olarak sadece bir tip token, bayt için bir token bulunmasına yol açar.

Birileri ikili verileri ayrıştırmak için bir lexer / ayrıştırıcıyla ayrıştırmanın neden ayrıştırma dersi almayan, ancak teoriye dayanan bir CS öğrencisi için yeterince açık olduğunu açıklayabilir mi?


Benim tahminim lexer muhtemelen bir bayt / sözcükten daha küçük jetonlar bulamıyor. İhtiyacınız olursa, Erlang ikili dosyaları ayrıştırmak için mükemmel bir desteğe sahiptir: user.it.uu.se/~pergu/papers/JFP_06.pdf
Dave Clarke

3
Varsayımınızın doğru olduğunu düşünmüyorum. Açıkçası, sigara bağlamdan bağımsız veri pozlar problemleri (genellikle circumvente olabilir), ancak yapabilirsiniz ikili kelimeler için dilbilgisi verir. Olarak Muhtemelen popüler ayrıştırıcı jeneratör kullanılmak üzere mümkün olmayacaktır bu metin girişi varsayalım. Yine de bu başka bir mesele.
Raphael

@GuyCoder: gramerler için birçok klasik örnekler ikili alfabe kullanmak, örneğin . S0S10S
Raphael

1
Bu arada: "sadece bir tür belirteç, bayt için bir belirteç var." - hayır, bu baytlık jetonlar yapar. 28
Raphael

5
@GuyCoder: Başka bir program tarafından oluşturulan tüm veriler bir dilbilgisi ile açıklanabilir. Yine de bağlamdan bağımsız olmayabilir.
Raphael

Yanıtlar:


10

Prensip olarak, yanlış bir şey yoktur.

Uygulamada,

  • bildiğim metinsel olmayan veri formatlarının çoğu bağlamsız değildir ve bu nedenle yaygın ayrıştırıcı jeneratörleri için uygun değildir. En yaygın neden, bir üretimin kaç kez mevcut olması gerektiğini veren uzunluk alanlarına sahip olmalarıdır.

    Açıkçası, bağlamsız bir dile sahip olmak ayrıştırıcı üreticilerinin kullanımını hiçbir zaman engellememiştir: dilin bir üst kümesini ayrıştırır ve daha sonra onu istediğimiz şeye indirmek için semantik kuralları kullanırız. Eğer sonuç deterministik olursa bu yaklaşım metin dışı formatlar için kullanılabilir. Sorun, çoğu ikili biçimin rasgele verilerin gömülmesine izin verdiği için eşitlenecek sayımlardan başka bir şey bulmaktır; uzunluk alanları size ne kadar olduğunu söyler.

    Daha sonra, ayrıştırıcıdan gelen geri bildirimlerle manuel olarak yazılmış bir lexer'a sahip olmak gibi hileler oynamaya başlayabilirsiniz (örneğin, lex / yacc C'nin işlenmesi, örneğin typedef'i işlemek için bu tür hileler kullanır). Ama sonra ikinci noktaya geliyoruz.

  • metinsel olmayan veri formatlarının çoğu oldukça basittir (bağlamsız olmasalar bile). Yukarıda sayılanlar göz ardı edildiğinde, diller normaldir, en kötü ihtimalle LL1'dir ve bu nedenle manuel ayrıştırma teknikleri için çok uygundur. Yinelenen iniş gibi manuel ayrıştırma teknikleri için işlem sayıları kolaydır.


İkili verilerin bir dilbilgisi olduğu anlamına gelmek için "diller düzenli" ise "içeriğe duyarlı" olarak alınmışsa, yanıtta açıklığa kavuşacağım. Bu sorunun bir parçası haline gelir; ayrıştırıcıdan söz et
Guy Coder

7

Verileri üç kategoriye ayıralım: insanlar tarafından okunabilen veriler (genellikle metinler, kitaplardan programlara değişir), bilgisayarlar ve diğer veriler tarafından okunması amaçlanan veriler (görüntü veya ses ayrıştırma).

İlk kategori için, bunları bir bilgisayarın kullanabileceği bir şey olarak işlememiz gerekir. İnsanlar tarafından kullanılan diller ayrıştırıcılar tarafından genellikle iyi yakalandığından, bunun için genellikle ayrıştırıcılar kullanırız.

Üçüncü kategorideki verilere örnek olarak, metinden ayrıştırmak istediğiniz bir kitabın dışındaki bir sayfanın taranmış görüntüsü verilebilir. Bu kategori için, girdileriniz hakkında neredeyse her zaman çok özel bilgiye ihtiyacınız vardır ve bu nedenle onu ayrıştırmak için belirli bir programa ihtiyacınız vardır. Standart ayrıştırma teknolojisi sizi bu kadar ileri götürmez.

Sorunuz ikinci kategori hakkında: ikili verilerimiz varsa, neredeyse her zaman başka bir bilgisayar programı için tasarlanmış bir bilgisayar programının ürünüdür. Bu, aynı zamanda, verilerin içinde bulunduğu biçimin oluşturulmasından sorumlu program tarafından seçildiği anlamına da gelir.

Bilgisayar programları neredeyse her zaman net bir yapıya sahip formatta veri üretir. Bir girdiyi ayrıştırırsak, temelde girdinin yapısını anlamaya çalışıyoruz . İkili verilerle, bu yapı genellikle çok basittir ve bilgisayarlar tarafından ayrıştırılması kolaydır.

Başka bir deyişle, yapıyı zaten bildiğiniz bir girdinin yapısını bulmak normalde biraz ziyan olur. Ayrıştırma ücretsiz olmadığından (zaman alır ve programınıza karmaşıklık katar), bu nedenle ikili verilerde lexers / ayrıştırıcıları kullanmak 'çok yanlıştır'.


2
Bu güzel bir bakış açısı, ama soruyu cevaplamıyor gibi hissediyorum.
Raphael

LANGSEC: Language-theoretic Securityilginç bir bakış açısı sunuyor. Makalelerden biri "garip makineler" hakkında konuşuyor: bir sistemin girdi işleme tesislerini oluşturan bilinen bir biçime sahip geçici ayrıştırıcılar . Aslında amaçlandığı gibi çalışmayabilirler. Yanlış varsayımlar nedeniyle, arızalı makine, özel hazırlanmış girdi verildiğinde beklenmeyen durum geçişleri gerçekleştirir ve mümkün olmaması gereken hesaplamaları yapar. Bu bir saldırı vektörü oluşturur. Biçimsel gramerlerin kullanılması muhtemelen doğru algoritmalar sağlayacaktır.
Matheus Moreira

0

a+b×(cd)+e(+ a (* b (- c d)) e)a b c d - * + e +. Her zamanki matematiksel gösterim, Lisp'den daha fazla yedekliliğe sahiptir (bu daha fazla parantez gerektirir, ancak ücretsiz değişkenler alır, bu nedenle büyük harflerle ifadeleri ifade etmek için daha az sembol gerektirir) veya RPL (hiçbir zaman parantez gerektirmez). Bu fazlalık bilgisayarlar için nadiren kullanışlıdır - ve bu durumda verilerde hatalar olabiliyorsa, hata düzeltme mantığı genellikle verilerin işlevsel anlamından ayrı tutulur, örneğin, keyfi olarak uygulanan hata düzeltme kodları kullanılarak temsil ettiklerinden bağımsız olarak bayt dizileri.

İkili biçimler genellikle kompakt olacak şekilde tasarlanmıştır; bu, bağlamsız gramerlerle ifade edilebilen dengeli parantez gibi birkaç basit dil özelliği anlamına gelir. Ayrıca, verilerin ikili temsillerinin kanonik olması, yani her bir nesnenin tek bir temsili olması genellikle yararlıdır. Bu parantez gibi bazen gereksiz özellikleri ortadan kaldırır. Daha az yedekliliğe sahip olmanın bir başka, daha az övgüye değer sonucu, her giriş sözdizimsel olarak doğru ise, hata kontrolünden tasarruf etmesidir.

İkili veriler için önemsiz ayrıştırıcılara karşı bir başka faktör, çok sayıda ikili biçimin, az ek yük ile sabit bellekte çalışmayı seven düşük düzey kodla ayrıştırılmak üzere tasarlanmasıdır. Bir öğenin keyfi olarak tekrarlanmasına izin vermek için uygulanabilir olduğunda sabit boyutlar tercih edilir. Soldan sağa bir ayrıştırıcının önce bir nesne için doğru miktarda bellek ayırmasını, ardından nesnenin temsilini okumasını sağlayan TLV gibi bir biçim . Soldan sağa ayrıştırma bir avantajdır, çünkü verilerin ara tampon olmadan geldiği gibi işlenmesine izin verir.


İlk iki paragrafın anlamı nedir? Artıklığınız olmasa bile bir ayrıştırıcıya ihtiyacınız vardır. Ayrıca, ilk paragraf yanlıştır: tüm kelimelere izin verilen örnekler vardır, ancak yapıyı elde etmek için ayrışırsınız (örneğin RNA'nın ikincil yapı tahmini).
Raphael

@Raphael Önemsiz bir ayrıştırıcı genellikle fazlalık anlamına gelir (evet, işaret ettiğiniz gibi, istisnalar vardır). Ne insanlar ne de bilgisayarlar için tasarlanmamış dilleri düşünmemiştim, bu ilginç bir örnek. İlk iki paragraf ikili ve insan tarafından okunabilir formatlar arasındaki tipik farkları tartışır (istisnaları aramaya giderseniz bunları bulacağınız tipik anlamı).
Gilles 'SO- kötü olmayı kes'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.