15

"Non esiste una" lingua compilata "o una" lingua interpretata ". Se un implementatore linguistico sceglie di scrivere un compilatore, un interprete o qualsiasi cosa nel mezzo è un dettaglio di implementazione e non ha nulla a che fare con la lingua. "Non esiste una "lingua compilata" o una "lingua interpretata"

L'affermazione sopra è vera?

+1

È questo compito? – bcat

+0

Questa domanda sembra un compito? – Tony

+1

Da dove stai citando? –

risposta

14

Sì, è vero nella più restrittiva interpretazione. Ad esempio, puoi trovare sia un C++ interpreter sia un Javascript compiler. Tuttavia, troverete che alcuni tipi di linguaggi (tipicamente, ad esempio, tipicamente) si prestano bene alla compilazione del codice nativo. Altri linguaggi (ad esempio, digitati dinamicamente) vengono comunemente implementati utilizzando la compilazione bytecode combinata con un ambiente di esecuzione della macchina virtuale.

3

Sort of. Generalmente, sia gli interpreti che i compilatori devono prima analizzare il codice sorgente e trasformarlo in una rappresentazione, chiamata AST (albero sintattico astratto). Un compilatore trasforma quindi l'AST in codice eseguibile (attraverso varie trasformazioni), mentre un interprete potrebbe semplicemente "interpretare" l'AST o talvolta compilarlo ed eseguirlo (compilazione just-in-time).

L'affermazione è corretta in quanto ciò non ha nulla a che fare con il linguaggio: in teoria, è possibile scrivere un interprete e un compilatore per qualsiasi lingua. Quale usare dipende in realtà dal caso d'uso, dallo scenario e dall'ambiente.

Un compilatore ha il vantaggio che ha solo bisogno di fare il suo lavoro una volta, indipendentemente da quanto spesso si esegue il programma. Un interprete deve analizzare la sorgente ogni volta (o fare un po 'di memorizzazione nella cache), quindi si ha un sovraccarico per ogni esecuzione che potrebbe richiedere più tempo rispetto al tempo di esecuzione effettivo del programma finale. D'altra parte, un interprete è più flessibile (può prendere in considerazione l'ambiente corrente e quindi fare ottimizzazioni che un compilatore non è autorizzato a fare). Ma le differenze non si fermano qui, questi sono solo due punti ovvi.

+0

Ho scritto diversi interpreti e compilatori: nessuno di loro ha creato o utilizzato un AST. –

+0

Cosa hai usato invece? E come hai fatto l'analisi semantica? – DarkDust

0

L'affermazione sopra è vera.

Quindi di nuovo, si potrebbe obiettare che non è abbastanza vero nel mondo reale. Se tutte le implementazioni esistenti di una lingua si basano sulla compilazione, la lingua può essere legittimamente definita come linguaggio compilato.

1

Il linguaggio design ha a che fare con la grammatica per la parte di input di livello superiore e il codice di output di livello inferiore che viene eseguito sul target.

C'è un albero di sintassi astratto tra i due.

Tradizionalmente, se si scrive il codice di uscita di livello inferiore da eseguire su una particolare piattaforma hardware e il relativo set di istruzioni specifico, l'output viene "compilato".

Se qualcuno decide di scrivere un interprete come obiettivo, il codice di uscita è il set di istruzioni o il codice byte che l'interprete si aspetta. Il livello aggiuntivo di riferimento indiretto indica che il codice interpretato può essere eseguito su qualsiasi piattaforma hardware con un'implementazione di interprete.

Quindi la frase è corretta se chiamiamo "linguaggio design" la grammatica e il pezzo lexer/parser.

Non è strettamente corretto se stiamo parlando del generatore di codice.

È possibile emettere un particolare linguaggio sia come interpretato sia compilato semplicemente chiamando generatori di codice diversi per percorrere l'AST.

Quindi forse è così che la distinzione è sfocata. Ma penso che sia ancora lì.

+0

Penso che tu abbia frainteso la domanda. Nessuno sta negando l'esistenza di compilatori e interpreti. Ciò che viene negato è l'esistenza di linguaggi compilati e lingue interpretate. Una lingua è solo un insieme di regole matematiche astratte. Una lingua non è compilata o interpretata. Una lingua solo * è *. Come prova, basta prendere uno dei milioni di linguaggi di programmazione per i quali esiste * no * implementazione. (Dì, Smalltalk-71 o Modula-1.) –

+0

Sto dicendo praticamente quello che dicono gli altri. Com'è che sono stato scelto come colui che fraintende? Sto parlando dei dettagli di implementazione sottostanti, ma giungendo alla stessa conclusione della maggior parte degli altri intervistati. – duffymo

0

È vero solo nel senso che alla fine sia le lingue compilate che quelle interpretate devono generare codice macchina. Ha un effetto sulla lingua in quanto tradizionalmente certi paradigmi sono più facili in uno rispetto all'altro. Ad esempio, in generale, chiusure o blocchi sono più facili da implementare nelle lingue interposte rispetto alle lingue compilate. Questo è vero poiché non esiste alcuna differenza tra tempo di compilazione e scope di runtime in linguaggi interpretati. Pertanto, lo scope dinamico TENDS è più facile da implementare nei linguaggi interpretati.

+1

Le lingue interpretate in modo semplice non generano mai codice macchina. Piuttosto, ogni istruzione verrà elaborata utilizzando l'equivalente di un albero if-ifelse-else o di un'istruzione switch-case. L'interprete non genera alcun codice macchina dalle dichiarazioni che esamina; piuttosto, semplicemente fa direttamente le azioni appropriate. – supercat

0

Una determinata implementazione di un linguaggio sarà o un compilatore "puro" (il cui output viene eseguito da un processore come codice), un interprete "puro" (ogni istruzione viene esaminata per la prima volta, in forma raw-source , come viene eseguito, e nulla sull'interpretazione viene memorizzato nella cache), o un ibrido tra i due. È abbastanza facile distinguere i casi "puri" dagli ibridi, ma alcuni ibridi sono "più vicini" ad essere compilati rispetto ad altri; le linee tra un ibrido "compilato" e un "interpretato" possono essere piuttosto confuse.

Non credo che nessun linguaggio sia in uso sostanziale, diverso dal linguaggio assembly (per il quale il termine "assemblatore" è solitamente usato in preferenza a "compilatore"), che non potrebbe essere implementato almeno in qualche modo praticamente in un interprete ibrido (l'esecuzione di un interprete "puro" è atta ad essere orribile con qualsiasi costrutto ciclico più banale). Esistono tuttavia alcuni linguaggi che consentono la generazione di codice dinamico in modi che non sarebbero suscettibili di essere compilati.

Per inciso, quando dico "forma grezza", non intendo sempre il formato del testo. Il mio primo calcolatore programmabile aveva 99 passi di programma, ognuno dei quali poteva essere configurato con una sequenza di tasti o una delle poche istruzioni speciali di sequenziamento. Il programma non sarebbe mai esistito in una forma di testo leggibile dall'uomo in sé, ma piuttosto come una sequenza di numeri chiave. Ciò nondimeno, lo descriverei come un "linguaggio" puramente interpretato poiché ogni fase del programma è stata valutata in modo completamente indipendente.

0

L'intera cosa del compilatore/interprete dipende in qualche modo da quali sono le tue intenzioni per il tuo programma. Un programma compilato è uno che viene trasformato in codice macchina. Un interprete è usato per leggere una lingua intermedia ed eseguirlo sulla macchina. Ad esempio, quando compili Java, viene trasformato in Java Bytecode e viene letto ed eseguito dall'interprete (che rappresenta anche lo svantaggio di velocità rispetto a C++).

Non penso davvero che la tua affermazione a riguardo del fatto che non abbia nulla a che fare con il linguaggio sia completamente vera. Una delle cose principali di Java è che dovrebbe essere eseguibile su diverse architetture. Se fosse compilato non sarebbe possibile.

+0

"Un programma compilato è uno che viene trasformato in codice macchina". I compilatori non indirizzano sempre il codice della macchina. Ad esempio, i compilatori C# e OCaml generano bytecode per macchine virtuali. –

0

Vale la pena notare che, per (alcuni?) Linguaggi che includono un'istruzione di tipo "eval" (specialmente se non è possibile determinare fino al runtime se un determinato blocco è codice o dati), anche la versione più puramente compilata di il dato programma deve essere parzialmente interpretato. Per tali linguaggi, non è possibile compilarli completamente (il codice compilato deve contenere un interprete per la lingua).

Come esempio, si consideri il seguente codice:

set s [eval {sum $a $b $c}] 

Per quanto sopra codice Tcl, non è possibile determinare fino runtime se il blocco (all'interno del {}) è codice o meno.

+0

-1 "deve essere parzialmente interpretato". Non devi ancora interpretare. –

+0

Come, esattamente, andresti a compilare un blocco come sopra quando non puoi essere sicuro se parti di esso sono dati o codice? O, meglio ancora, codice come [$ something {sum $ b $ c}] ... che non sai se il valore della variabile $ qualcosa è [eval] o [puts] (che significa il valore nel riccio le parentesi potrebbero essere codice o dati) fino al runtime. – RHSeeger

+0

Nello stesso modo in cui SBCL compila '(EVAL '(+ 2 3))' o qualsiasi altro linguaggio compilato che supporti la metaprogrammazione. Il codice è dati non preclude la compilazione. –