Cerchi una chiara definizione di cosa sono un “tokenizer”, “parser” e “lexers” e come sono correlati tra loro e utilizzati?

Sto cercando una chiara definizione di cosa sono un “tokenizer”, “parser” e “lexer” e come sono correlati tra loro (ad esempio, un parser usa un tokenizer o viceversa)? Ho bisogno di creare un programma passerà attraverso i file sorgente c / h per estrarre la dichiarazione e le definizioni dei dati.

Ho cercato degli esempi e sono riuscito a trovare alcune informazioni, ma ho davvero difficoltà a comprendere i concetti sottostanti come le regole grammaticali, gli alberi di analisi e l’albero di syntax astratto e il modo in cui interagiscono tra loro. Alla fine questi concetti devono essere memorizzati in un programma reale, ma 1) come sono, 2) ci sono implementazioni comuni.

Ho esaminato Wikipedia su questi argomenti e programmi come Lex e Yacc, ma non avendo mai seguito una class di compilatore (EE major) trovo difficile comprendere appieno cosa sta succedendo.

Un tokenizzatore interrompe un stream di testo in token, in genere cercando spazi bianchi (tabulazioni, spazi, nuove linee).

Un lexer è fondamentalmente un tokenizer, ma di solito attribuisce un contesto extra ai token – questo token è un numero, che token è un letterale stringa, questo altro token è un operatore di uguaglianza.

Un parser prende il stream di token dal lexer e lo trasforma in un albero di syntax astratto che rappresenta il programma (di solito) rappresentato dal testo originale.

L’ultima volta che ho controllato, il miglior libro sull’argomento era “Compilatori: Principi, Tecniche e Strumenti”, solitamente noto come “Il Libro del Drago”.

Esempio:

int x = 1; 

Un lexer o tokeniser lo dividerà in token ‘int’, ‘x’, ‘=’, ‘1’, ‘;’.

Un parser prenderà quei token e li userà per capire in qualche modo:

  • abbiamo una dichiarazione
  • è una definizione di un intero
  • il numero intero è chiamato ‘x’
  • ‘x’ dovrebbe essere inizializzato con il valore 1

Direi che un lexer e un tokenizer sono fondamentalmente la stessa cosa e che distruggono il testo nelle sue parti componenti (i “token”). Il parser quindi interpreta i token utilizzando una grammatica.

Tuttavia, non mi sentirei troppo attaccato a un preciso uso terminologico: le persone spesso usano il “parsing” per descrivere qualsiasi azione di interpretazione di un pezzo di testo.

( aggiungendo alle risposte date )

  • Tokenizer rimuoverà anche eventuali commenti e restituirà solo token al Lexer.
  • Lexer definirà anche gli ambiti per quei token (variabili / funzioni)
  • Parser quindi costruirà la struttura del codice / programma