Perché usare un lexer / parser su dati binari è così sbagliato?


13

Lavoro spesso con lexer / parser , al contrario di un combinatore di parser e vedo persone che non hanno mai frequentato un corso di analisi, chiedendo di analizzare i dati binari. In genere i dati non sono solo binari ma anche sensibili al contesto. Questo in pratica porta ad avere un solo tipo di token, un token per byte.

Qualcuno può spiegare perché l'analisi dei dati binari con un lexer / parser è così sbagliata con abbastanza chiarezza per uno studente CS che non ha preso una classe di analisi, ma con un fondamento sulla teoria?


La mia ipotesi è che probabilmente il lexer non riesce a trovare token più piccoli di un byte / parola. Se ne hai bisogno, Erlang ha un eccellente supporto per l'analisi dei file binari: user.it.uu.se/~pergu/papers/JFP_06.pdf
Dave Clarke

3
Non penso che la tua ipotesi sia vera. Ovviamente, i dati privi di contesto non creano problemi (che possono essere spesso circumventi), ma è possibile fornire grammatiche per parole binarie. Probabilmente non sarai in grado di utilizzare i generatori di parser più diffusi, dato che questi assumono il testo inserito. Questo è un altro problema, però.
Raffaello

@GuyCoder: molti esempi classici di grammatica usano alfabeti binari, ad esempio da . S0S|10S
Raffaello

1
A proposito: "avere un solo tipo di token, un token per byte". - beh no, ciò renderebbe token di byte. 28
Raffaello

5
@GuyCoder: tutti i dati generati da un altro programma possono essere descritti da una grammatica. Tuttavia, potrebbe non essere privo di contesto.
Raffaello

Risposte:


10

In linea di principio, non c'è nulla di sbagliato.

In pratica,

  • la maggior parte dei formati di dati non testuali che conosco non sono privi di contesto e non sono quindi adatti per generatori di parser comuni. Il motivo più comune è che hanno campi di lunghezza che indicano il numero di volte in cui una produzione deve essere presente.

    Ovviamente, avere un linguaggio non privo di contesto non ha mai impedito l'uso di generatori di parser: analizziamo un superset del linguaggio e quindi usiamo regole semantiche per ridurlo a ciò che vogliamo. Tale approccio potrebbe essere utilizzato per formati non testuali se il risultato fosse deterministico. Il problema è trovare qualcos'altro oltre a contare su cui sincronizzarsi poiché la maggior parte dei formati binari consente l'integrazione di dati arbitrari; i campi di lunghezza ti dicono quanto costa.

    Puoi quindi iniziare a giocare a trucchi come avere un lexer scritto manualmente in grado di gestirlo con il feedback del parser (la gestione lex / yacc di C usa quel tipo di trucchi per gestire typedef, per esempio). Ma poi arriviamo al secondo punto.

  • la maggior parte dei formati di dati non testuali sono abbastanza semplici (anche se non sono privi di contesto). Quando i conteggi sopra menzionati vengono ignorati, le lingue sono regolari, LL1 nel peggiore dei casi, e sono quindi adatte per le tecniche di analisi manuale. E la gestione dei conteggi è semplice per le tecniche di analisi manuale come la discesa ricorsiva.


"le lingue sono regolari" Se "ma anche sensibile al contesto" è stato assunto per indicare che i dati binari sono una grammatica, chiarirò la risposta. Ciò arriva a una parte del problema; le persone tendono a pensare a grammatiche o lingue regolari una volta che menzionare parser
Guy Coder,

7

Classifichiamo i dati in tre categorie: dati leggibili dall'uomo (di solito testi, che variano da libri a programmi), dati che devono essere letti da computer e altri dati (analisi di immagini o suoni).

Per la prima categoria, dobbiamo trasformarli in qualcosa che un computer può usare. Dato che le lingue usate dagli umani in genere possono essere catturate relativamente bene dai parser, di solito usiamo i parser per questo.

Un esempio di dati nella terza categoria potrebbe essere un'immagine digitalizzata di una pagina di un libro che si desidera analizzare nel testo. Per questa categoria, hai quasi sempre bisogno di conoscenze molto specifiche sui tuoi input, e quindi hai bisogno di un programma specifico per analizzarli. La tecnologia di analisi standard non ti porterà molto lontano qui.

La tua domanda riguarda la seconda categoria: se disponiamo di dati binari, è quasi sempre un prodotto di un programma per computer, destinato a un altro programma per computer. Ciò significa immediatamente anche che il formato in cui si trovano i dati è scelto dal programma responsabile della sua creazione.

I programmi per computer producono quasi sempre dati in un formato che ha una struttura chiara. Se analizziamo alcuni input, stiamo essenzialmente cercando di capire la struttura dell'input. Con i dati binari, questa struttura è generalmente molto semplice e facile da analizzare dai computer.

In altre parole, normalmente è un po 'uno spreco capire la struttura di un input per il quale già conosci la struttura. Poiché l'analisi non è gratuita (richiede tempo e aggiunge complessità al programma), è per questo che l'utilizzo di lexer / parser su dati binari è "così sbagliato".


2
Questa è una bella prospettiva, ma sento che non risponde alla domanda.
Raffaello

LANGSEC: Language-theoretic Securityoffre una prospettiva interessante. Uno degli articoli parla di "macchine strane": parser ad hoc di un formato noto che formano le strutture di gestione dell'input di un sistema. In realtà potrebbero non funzionare come previsto. A causa di ipotesi errate, la macchina difettosa eseguirà transizioni di stato impreviste con input appositamente predisposti, eseguendo calcoli che non dovrebbero essere possibili. Questo crea un vettore di attacco. L'uso di grammatiche formali produrrebbe algoritmi dimostrabili corretti.
Matheus Moreira,

0

un'+B×(c-d)+e(+ a (* b (- c d)) e)a b c d - * + e +. La solita notazione matematica ha più ridondanza rispetto a Lisp (che richiede più parentesi, ma ottiene arità variabili gratuitamente, quindi richiede meno simboli per esprimere espressioni usando arità di grandi dimensioni) o RPL (che non ha mai bisogno di parentesi). Tale ridondanza è raramente utile per i computer - e laddove si trova, ovvero quando potrebbero esserci errori nei dati, la logica di correzione degli errori viene generalmente mantenuta separata dal significato funzionale dei dati, ad esempio utilizzando codici di correzione degli errori che si applicano ad arbitrari sequenze di byte indipendentemente da ciò che rappresentano.

I formati binari sono in genere progettati per essere compatti, il che significa poche funzioni linguistiche semplici come parentesi bilanciate che sono espresse da grammatiche senza contesto. Inoltre, è spesso utile che le rappresentazioni binarie di dati siano canoniche, ovvero che abbiano una singola rappresentazione di ciascun oggetto. Questo esclude funzionalità a volte ridondanti come le parentesi. Un'altra conseguenza, meno encomiabile, della riduzione della ridondanza è che se ogni input è sintatticamente corretto, risparmia sul controllo degli errori.

Un altro fattore contro i parser non banali per i dati binari è che molti formati binari sono progettati per essere analizzati da un codice di basso livello a cui piace operare in memoria costante con un sovraccarico minimo. Le dimensioni fisse sono preferite quando applicabili per consentire la ripetizione arbitraria di un elemento. Un formato come TLV che consente a un parser da sinistra a destra di allocare prima la giusta quantità di memoria per un oggetto, quindi leggere la rappresentazione dell'oggetto. L'analisi da sinistra a destra è un vantaggio perché consente di elaborare i dati così come sono, senza buffer intermedio.


Qual è il punto dei primi due paragrafi? Anche se non si ha ridondanza, è necessario un parser. Inoltre, il primo paragrafo è sbagliato: ci sono esempi in cui sono consentite tutte le parole ma si analizza per ottenere la struttura (ad esempio la previsione della struttura secondaria dell'RNA).
Raffaello

@Raphael Un parser non banale di solito implica ridondanza (sì, come fai notare, ci sono eccezioni). Non avevo considerato le lingue che non erano progettate né per l'uomo né per i computer, questo è un esempio interessante. I primi due paragrafi discutono le differenze tipiche tra i formati binari e leggibili dall'uomo (significato tipico che se vai alla ricerca di eccezioni, le troverai).
Gilles 'SO- smetti di essere malvagio' il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.