2015-09-25 20 views
7

Ho lavorato su Java da più di 8 anni.Internal Architecture of Java Compiler

La scorsa settimana, in una piccola riunione nella mia azienda, uno dei miei colleghi mi ha chiesto come funziona esattamente lo Java Compiler? Ero senza risposta.

Ho provato a spiegare, come Java Compilatore prende le istruzioni una per una e le converte in codice byte che non è indirizzato a qualsiasi OS ma a JVM.

Nessuno soddisfatto di quella risposta nemmeno io.

Ora la domanda principale è come funziona esattamente il compilatore java. cioè quanti passi o fasi o fasi ci sono che saranno fatte dal compilatore in caso di compilazione di un file Java.

Che cosa è esattamente l'architettura Java's compiler?

Cosa succede se ci sono più Java classes nello stesso file .java. Quindi quante classi verranno compilate.

Cosa succede se ci sono importazioni che puntano a classi Java non compilate? Quindi le classi non compilate possono essere compilate o ignorate?

Ho cercato su Google per più di mezza giornata e tutti stanno fornendo la stessa risposta che ho dato ai miei colleghi.

Ma alla fine ho trovato qualche utile tutorial here.

Ma il tutorial copre anche non troppo in profondità e non ho potuto visualizzare quel tutorial.

Ancora non sono soddisfatto e desideroso di imparare qualcosa di più su questo da voi.

Quindi, se qualcuno sa qualcosa di più di me e del blog di cui sopra, qualcosa con cui posso visualizzare quale sia esattamente l'architettura interna di Java Compiler per favore spiegami.

+0

La specifica JVM è abbastanza dettagliata: https://docs.oracle.com/javase/specs/jvms/se8/html/index.html –

+0

[Come avviene esattamente la compilazione java] (http: // stackoverflow. com/domande/3406942/come-esattamente-fa-java-compilazione-take-place). – YoungHobbit

+0

[La Java Virtual Machine] (https://www.artima.com/insidejvm/ed2/jvmP.html). – YoungHobbit

risposta

7

alcuni passaggi fondamentali:

  1. analisi: legge un insieme di file di origine * .java e mappe la risultante di token sequenza in AST (Abstract Syntax Tree) -nodes.
  2. invio: immette i simboli per le definizioni nella tabella dei simboli.
  3. annotazioni di processo: se richiesto, elabora le annotazioni rilevate in le unità di compilazione specificate.
  4. attributo
  5. : Attribuisce gli alberi di sintassi. Questo passaggio include la risoluzione del nome , il controllo del tipo e il piegamento costante.
  6. flusso
  7. : esegue l'analisi del flusso di dati sugli alberi dal passaggio precedente. Questo include controlli per assegnazioni e raggiungibilità.
  8. desugar: Riscrive l'AST e traduce via dello zucchero sintattico.
  9. generare: genera file di origine o file di classe.

Nel dettaglio:

  1. Lex - Rompere il file sorgente in singole parole, o gettoni.
  2. Analizza - Analizza la struttura della frase del programma.
  3. Azioni semantiche: crea un pezzo di albero di sintassi astratto corrispondente a ciascuna frase.
  4. Analisi semantica - Determinare cosa significa ogni frase, mettere in relazione gli usi delle variabili con le loro definizioni, controllare i tipi di espressioni, richiedere la traduzione di ogni frase.
  5. Layout della cornice: inserire variabili, parametri di funzione, ecc. Nei record di attivazione (frame di stack) in modo dipendente dalla macchina.
  6. Translate - Produce alberi di rappresentazione intermedi (alberi IR), una notazione che non è legata a una particolare lingua di origine o all'architettura di targetachine.
  7. Canonicalizza - Estrarre gli effetti collaterali dalle espressioni e ripulire i rami condizionali, per comodità delle fasi successive.
  8. Selezione istruzione: raggruppare i nodi dell'albero IR in gruppi che corrispondono alle azioni delle istruzioni della macchina target.
  9. Analisi del flusso di controllo - Analizzare la sequenza di istruzioni in un grafico del flusso di controllo che mostra tutti i possibili flussi di controllo che il programma potrebbe seguire durante l'esecuzione.

  10. Analisi del flusso di dati: raccogliere informazioni sul flusso di informazioni tramite variabili del programma; ad esempio, l'analisi della vividezza calcola i luoghi in cui ciascuna variabile di programma mantiene un valore ancora necessario (è in diretta).

  11. Assegnazione registro: scegliere un registro per contenere ciascuna delle variabili e valori temporanei utilizzati dal programma; le variabili non vivono allo stesso tempo possono condividere lo stesso registro.

  12. Emissione codice: sostituire i nomi temporanei in ciascuna istruzione macchina con i registri delle macchine .

C'è un bel libro:

moderna Compiler Implementazione in Java

si consiglia di guardare dentro il codice javac:

Javac Documentation

OpenJDK source code

Hacker's guide to javac

Don't Panic! To help newcomers to javac navigate their way around the code base

JVM JLS

+0

Includere gentilmente l'indirizzo del sito Web del file PDF che è stato incluso ed eliminato. – Jagadeesh

+0

L'ho rimesso a posto. Grazie – ACV

6

Ci sono diversi passaggi su un compilatore, ma qui sono i più importanti:

Analisi lessicale Il primo passo è l'analisi lessicale. Fondamentalmente questo passi gettoni estratto dal codice Java (parole chiave, operatori, separatori, commenti, nomi di variabili ...)

analisi di sintassi (parser) Il secondo passo è l'analisi della sintassi. I token sono presi come input dall'analisi lessicale e sono combinati per formare espressioni e istruzioni.

ottimizzazione e la conversione di codice di byte L'ultima macro passo è la conversione il passaggio precedente per byte code. Qui il codice può essere modificato per essere equivalente al codice originale ma più efficiente.


Nota: Questo processo non è legato solo a Java, ma è comune a tutti i compilatori. Anche compilatori che non generano un codice byte intermedio ma un codice macchina (come compilatori per C o C++).

Generalmente esistono strumenti per creare un analizzatore lessicale e un analizzatore di sintassi poiché questa procedura ha molte parti comuni tra lingue diverse.

An open source Analizer lessicale è flex Un utile Analizer sintattica è yacc

Entrambi funziona con C e C++ che sono le lingue più utilizzate per creare compilatori (java e altri troppo), ma esistono anche alternative simili per altri linguaggi di programmazione (per creare un compilatore in un'altra lingua, non per un'altra lingua). Fondamentalmente il linguaggio in cui è scritto un compilatore non è legato alla lingua compilata dal compilatore.