A compiler is a program that can read a program in one language – the source language – and translate it into an equivalent program in another language – the target language.
If the target program is an executable machine-language program, it can then be called by the user to process inputs and produce outputs.
An interpreter is another common kind of language processor which produce a target program as translation. An interpreter appears to directly execute the operations specified in the source program on inputs supplied by the user
The machine-language target program produced by a compiler is usually much faster than an interpreter at mapping inputs and outputs.
An interpreter can usually give better error diagnostics than a compiler because it executes the source program statement by statement.
Java language processors combine compilation and interpretation.
A Java source program first be compiled into bytecodes.
The bytecodes are then interpreted by a virtual machine.
A benefit of this arrangement is that bytecodes compile on machine can be interpreted on another machine or across the network.
Java compilers are called just-in-time compilers which translate bytecodes into machine language immediately before they run the intermediate program to process the input.
In addition to a compiler, sever other programs may be required to create an executable target program.
A source program may be divided into modules stored in separate files. The task of collecting the source program is sometimes entrusted to a separate program, called a preprocessor. The preprocessor may also expand shorthands, called macros, into source language statements.
The modified source program is then fed to a compiler. The compiler may produce an assembly-language program as its output, because assembly language is easier to produce as output and is easier to debug. The assembly language is then processed by a program called assembler that produces relocatable machine code as its output.
Large programs are often compiled in pieces, so the relocatable machine code may have to be linked together with other relocatable object files and library files into the code that actually runs on the machine. The linker resolve external memory addresses, where the code in one file may refer to a location in another file. The loader then puts together all the executable object files into memory for execution.