7

Qualcuno, in termini semplici, può spiegare che cosa significa "Sintassi della traduzione diretta"? Ho iniziato a leggere l'argomento dal Libro del Drago ma non ho potuto capire. Il Wiki article non ha aiutato neanche.Cosa significa traduzione diretta della sintassi?

+0

http://en.wikipedia.org/wiki/Syntax-directed_translation –

+1

@ 500-InternalServerError Grazie. Ma ho già letto quell'articolo. Non l'ho capito – saplingPro

risposta

17

In termini più semplici, "Sintassi di traslazione diretta" significa guidare l'intera procedura di compilazione (traduzione) con il sintassi di riconoscimento (il parser).

Concettualmente, il processo di compilazione di un programma (traslazione da codice sorgente a codice macchina) inizia con un parser che produce un albero di analisi e quindi trasforma tale albero di analisi in una sequenza di trasformazioni di alberi o grafici, ciascuna delle quali è in gran parte indipendente, risultante in un albero o un grafico semplificato finale che viene attraversato per produrre codice macchina.

Questa vista, seppur piacevole in teoria, ha uno svantaggio che se si tenta di implementarla direttamente, è necessaria memoria sufficiente per contenere almeno due copie dell'intero albero o grafico. Quando è stato scritto il Libro del Drago (e quando gran parte di questa teoria è stata sottoposta a revisione), i ricordi dei computer sono stati misurati in kilobyte e 64 KB erano molti. Quindi compilare programmi di grandi dimensioni potrebbe essere complicato.

Con la sintassi di traduzione diretta, si organizzano tutte le trasformazioni del grafico attorno all'ordine in cui il parser riconosce l'albero di analisi. Invece di produrre un albero di analisi completo, il parser ne crea piccoli frammenti e quindi li alimenta ai passaggi successivi del compilatore, producendo in ultima analisi un piccolo pezzo di codice macchina, prima di continuare il processo di analisi per creare il prossimo pezzo di analisi albero. Poiché solo piccole quantità dell'albero di analisi (o dei grafici successivi) esistono in qualsiasi momento, è necessaria molta meno memoria. Poiché il sintassi riconosce è il master sequencer che controlla tutto questo (decidendo l'ordine in cui le cose accadono), questo è chiamato Sintassi Directed Translation.

Poiché questo è un modo così efficace di tenere a bada l'uso della memoria, anche le lingue ridisegnate per renderlo più facile da fare - l'ideale è avere un compilatore "Single Pass" che potrebbe in effetti fare l'intero processo dall'analisi per generare codice in un unico passaggio.

Al giorno d'oggi, la memoria non è così conveniente, quindi c'è meno pressione per forzare tutto in un unico passaggio. In genere, si utilizza la sintassi Direct Translation solo per il front-end, l'analisi della sintassi, il controllo della digitazione e altri controlli semantici e alcune semplici trasformazioni, tutto dal parser e la produzione di qualche forma interna (tre codici di indirizzo, alberi o dags di qualche tipo) e quindi con l'ottimizzazione separata e i passaggi back-end indipendenti (e quindi non diretti alla sintassi). Anche in questo caso si potrebbe affermare che questi passaggi successivi sono diretti almeno in parte sulla sintassi, poiché il compilatore può essere organizzato per operare su grandi parti dell'input (come intere funzioni o moduli), spingendo attraverso tutti i passaggi prima di continuare con il prossimo pezzo di input.

Gli strumenti come yacc sono progettati attorno all'idea della traduzione diretta di sintassi - lo strumento produce un riconoscimento sintattico che esegue direttamente frammenti di codice ("azioni" nel linguaggio degli strumenti) quando le produzioni (frammenti dell'albero di analisi) vengono riconosciute , senza mai creare un vero 'albero'. Queste azioni possono richiamare direttamente ciò che in seguito logicamente passa nel compilatore, quindi tornare a continuare l'analisi. Il ciclo principale imperativo che guida tutto questo è la macchina dello stato di lettura dei token del parser.

+0

La maggior parte delle lingue interpretate è implementata in questo modo? – Josh

+0

@Josh: Molte lingue interpretate prima traducono il testo sorgente in bytecode o in qualche altra forma interna. Spesso la traduzione diretta alla sintassi viene utilizzata per questo passaggio. –

+0

In realtà, non devi tenere l'albero; devi solo guidare la traduzione dalla sintassi. Questo è in realtà semplice da usare usando lo stack di analisi come sostituto dell'albero (almeno il contesto di sinistra). Lo svantaggio è che il generatore di codice non può essere altrettanto valido. –

1

Prima del Libro del Drago c'erano compilatori di compilatori diretti alla sintassi. META II e TREE META sono stati sviluppati negli anni '60. Sono compilatori metalanguage (metacompilatori). Sono parser top-down che prendono un set di regole di parsing che sono in realtà funzioni che restituiscono il successo dell'errore. Ogni regola è un'espressione di analisi logica. La regola guida in alto ha definito il contenuto del file sorgente. Ad esempio un linguaggio di programmazione potrebbe essere costituito da una serie di dichiarazioni.Quindi la regola di guida sarebbe simile a:

program = $declarations; 

$ vale a dire zero o più. $ dichiarazioni specifica che la fonte che si sta compilando è composta da un numero di dichiarazioni. le dichiarazioni definiscono quindi i tipi di dichiarazioni. Potrebbero essere necessarie dichiarazioni di collegamenti esterni, dichiarazioni di dati, dichiarazioni di funzioni o procedure.

declarations = linkage_decl | data_decl | code_decl; 

I tipi di dichiarazioni essendo ciascuna una regola separata. La sintassi controllerebbe quando si verifica la generazione del codice. I metacompilatori controllavano l'elaborazione semantica dalle regole di sintassi. All'inizio nella regola è se stesso. Più tardi trasformarono la fonte in strutture ad albero ed elenco e le passarono a regole semantiche che producevano il loro output. Ad esempio, una dichiarazione di assegnazione aritmetica potrebbe essere trasformata e passata a una regola semantica.

asign = id '=' expr ';' :ASSIGN!2 arith_gen(*1); 
expr = term $(('+':ADD | '-':SUB) term !2); 
term = factor $(('*':MPY | '//' :REM | '/':DIV) factor!2); 
factor = id | number | '(' expr ')'; 

Si diceva che queste lingue fossero simili. Ma non è questo il caso. Si tratta di analizzatori di sintassi top-down analitici. arith_gen sarebbe quindi codificato per riconoscere le strutture ad albero generate dall'albero incorporato, ':' e '!' operatori. La notazione ad albero utilizzata è il nodo seguito dai rami di albero racchiusi tra "[" e "]" e separati da ",". La sintassi analitica sopra sta definendo la gerarchia matematica di un'espressione. moltiplicazione, divisione e resto eseguiti prima dell'aggiunta o sottrazione. Un'espressione di assegnazione aritmetica trasformata in un'espressione di lista funzionale. La sintassi sta dirigendo la trasformazione dell'input in una notazione funzionale.

x = a + (b - c)/d; 

produce un albero notazione funzionale: ASSIGN [x, ADD [a, DIV [SUB [b, c], d]]]

Questi vecchi metacompilers non corrispondono esattamente la terminologia corrente.

argomenti See Wiki metacompiler META II e TREE META e che è pagina di discussione per ulteriori informazioni