In quale processo si verifica l'errore di sintassi? (tokenizing o analisi)

23

Sto cercando di capire la compilazione e l'interpretazione, passo dopo passo, immaginando un'immagine totale. Quindi mi sono avvicinato a una domanda mentre leggevo link questo articolo

Dice:

The next stage of the compiler is called the Parser. This part of the compiler has an understanding of the language's grammar. It is responsible for identifying syntax errors and for translating an error free program into internal data structures that can be interpreted or written out in another language.

Ma non sono riuscito a capire come il tokenizzatore possa tokenizzare correttamente il flusso dato che ha l'errore di sintassi.

Dovrebbe essere bloccato lì o dare alcune informazioni sbagliate al parser. Voglio dire, non è la tokenizzazione anche una specie di traduttore?

Quindi, come ha appena superato le linee lessicali corrotte del codice durante la tokenizzazione.

C'è un esempio di token all'interno del link sopra all'intestazione The Tokenizer .

Come ho capito, la forma del token sembra, se c'è qualcosa di sbagliato nel codice, il token potrebbe essere danneggiato.

Potresti per favore chiarire il mio fraintendimento?

    
posta FZE 31.03.2016 - 22:35
fonte

3 risposte

32

Un tokenizzatore è solo un'ottimizzazione del parser. È perfettamente possibile implementare un parser senza tokenizer.

Un tokenizzatore (o un lexer o uno scanner) taglia l'input in una lista di token. Alcune parti della stringa (commenti, spazi bianchi) vengono solitamente ignorate. Ogni token ha un tipo (il significato di questa stringa nella lingua) e un valore (la stringa che costituisce il token). Ad esempio, lo snippet di origine PHP

$a + $b

potrebbe essere rappresentato dai token

Variable('$a'),
Plus('+'),
Variable('$b')

Il tokenizer non considera se un token è possibile in questo contesto. Ad esempio, l'input

$a $b + +

produrrebbe felicemente il flusso di token

Variable('$a'),
Variable('$b'),
Plus('+'),
Plus('+')

Quando il parser consuma questi token, noterà che due variabili non possono seguirsi l'una con l'altra, e nemmeno due operatori di infissi. (Nota che altre lingue hanno sintassi diverse in cui tale flusso di token può essere legale, ma non in PHP).

Un parser può ancora fallire nella fase tokenizer. Ad esempio, potrebbe esserci un carattere illegale:

$a × ½ — 3

Un tokenizzatore PHP non sarebbe in grado di associare questo input alle sue regole e produrrebbe un errore prima che inizi l'analisi principale.

Più formalmente, i tokenizer sono usati quando ogni token può essere descritto come un linguaggio normale . I token possono quindi essere abbinati in modo estremamente efficiente, possibilmente implementato come DFA. Al contrario, la grammatica principale di solito è libera dal contesto e richiede un algoritmo di parsing più complicato e meno performante come LALR.

    
risposta data 31.03.2016 - 22:57
fonte
16

avresti di solito aspettati che la maggior parte degli errori di sintassi provengano dal parser, non dal lexer.

Il lexer genera un errore se (e soprattutto solo se) c'è qualcosa nell'input che non può essere tokenizzato. In molte lingue, tuttavia, quasi tutte le sequenze di caratteri possono essere trasformate in token di qualche tipo, quindi gli errori qui sono piuttosto inusuali.

Il parser genera un errore se l'input contiene token validi, ma quei token non sono disposti in modo da formare dichiarazioni / espressioni valide nella lingua di destinazione. Questo è molto più comune di regola.

    
risposta data 31.03.2016 - 22:53
fonte
11

Tokenizer divide semplicemente il flusso di caratteri in token. Da tokenizer POV questo è completamente valido:

1 * * 1

e si traduce in qualcosa di simile: ["1", MULTIPLY, MULTIPLY, "1"] Solo il parser può rifiutare tali espressioni - sa che l'operatore di moltiplicazione non può seguire un altro operatore di moltiplicazione. Ad esempio in JavaScript questo produce:

Uncaught SyntaxError: Unexpected token *(…)

Ci sono errori che potrebbero essere rilevati da tokenizer. Ad esempio valori letterali stringa non completati: "abc o numeri non validi: 0x0abcdefg . Tuttavia potrebbero ancora essere segnalati come errori di sintassi:

Uncaught SyntaxError: Unexpected token ILLEGAL

Si noti tuttavia che il token non è stato riconosciuto ed è segnalato come ILLEGAL .

    
risposta data 31.03.2016 - 22:51
fonte

Leggi altre domande sui tag