Lably
Skip to content

Compiler

Software that translates code from one programming language to another

  • 26 min read
  • 5 chapters

Learn it on Lably

There are many different types of compilers which produce output in different useful forms. A cross-compiler produces code for a different central processing unit (CPU) or operating system than the one on which the cross-compiler itself runs. A bootstrap compiler is often a temporary compiler, used for compiling a more permanent or better optimized compiler for a language.

Related software include decompilers, programs that translate from low-level languages to higher-level ones; programs that translate between high-level languages, usually called source-to-source compilers or transpilers; language rewriters, usually programs that translate the form of expressions without a change of language; and compiler-compilers, compilers that produce compilers (or parts of them), often in a generic and reusable way so as to be able to produce many differing compilers.

A compiler is likely to perform some or all of the following operations, often called phases: preprocessing, lexical analysis, parsing, semantic analysis (syntax-directed translation), conversion of input programs to an intermediate representation, code optimization and machine specific code generation. Compilers generally implement these phases as modular components, promoting efficient design and correctness of transformations of source input to target output. Program faults caused by incorrect compiler behavior can be very difficult to track down and work around; therefore, compiler implementers invest significant effort to ensure compiler correctness.

Comparison with interpreter

With respect to making source code runnable, an interpreter provides a similar function as a compiler, but via a different mechanism. An interpreter executes code without converting it to machine code. Therefore, some interpreters execute source code while others execute an intermediate form such as bytecode.

A program compiled to native code tends to run faster than when interpreted, while environments with a bytecode-intermediate-form tends toward intermediate-speed. Alternatively, just-in-time compilation allows for native execution speed with a one-time startup processing time cost.

Low-level programming languages, such as assembly and C, are typically compiled, especially when speed is a significant concern, rather than having cross-platform support. For such languages, there are more one-to-one correspondences between the source code and the resulting machine code, making it easier for programmers to control the use of hardware.

In theory, any programming language can be used via either a compiler or an interpreter, but in practice, languages tend to be used with only one or the other. Nonetheless, it is possible to write a compiler for a language that is commonly interpreted. For example, Common Lisp can be compiled to Java bytecode (and then interpreted by the Java virtual machine), to C code (which can then be compiled again to native machine code), or directly to native code.

Sign in to keep reading

4 more chapters are free with a Lably account.

More in Computing and information technology