Working Of Compiler Step By Step


The phases of a compiler

                    Since writing a compiler is a nontrivial task, it is a good idea to structure the work. A typical way of doing this is to split the compilation into several phases with well-defined interfaces. Conceptually, these phases operate in sequence (though in practice, they are often interleaved), each phase (except the first) taking the output from the previous phase as its input. It is common to let each phase be handled by a separate module. Some of these modules are written by hand, while others may be generated from specifications. Often, some of the modules can be shared between several compilers. A common division into phases is described below. In some compilers, the ordering of phases may differ slightly, some phases may be combined or split into several phases or some extra phases may be inserted between those mentioned below.
  • Lexical analysis
                    This is the initial part of reading and analysing the program text: The text is read and divided into tokens, each of which corresponds to a symbol in the programming language, e.g., a variable name, keyword or number.
  • Syntax analysis
                    This phase takes the list of tokens produced by the lexical analysis and arranges these in a tree-structure (called the syntax tree) that reflects the structure of the program. This phase is often called parsing.
  • Type checking
                    This phase analyses the syntax tree to determine if the program violates certain consistency requirements, e.g., if a variable is used but not declared or if it is used in a context that does not make sense given the type of the variable, such as trying to use a boolean value as a function pointer.
  • Intermediate code generation
                    The program is translated to a simple machine independent intermediate language.
  • Register allocation
                    The symbolic variable names used in the intermediate code are translated to numbers, each of which corresponds to a register in the target machine code.
  • Machine code generation
                    The intermediate language is translated to assembly language (a textual representation of machine code) for a specific machine architecture.
  • Assembly and linking
                    The assembly-language code is translated into binary representation and addresses of variables, functions, etc., are determined.
Important
                    The first three phases are collectively called the front-end of the compiler and the last three phases are collectively called the back-end.
        The middle part of the compiler is in this context only the intermediate code generation, but this often includes various optimisations and transformations on the intermediate code. Each phase, through checking and transformation, establishes stronger invariants on the things it passes on to the next, so that writing each subsequent phase is easier than if these have to take all the preceding into account. 

For example, 
                    The type checker can assume absence of syntax errors and the code generation can assume absence of type errors. Assembly and linking are typically done by programs supplied by the machine or operating system vendor, and are hence not part of the compiler itself, so we will not further discuss these phases more.


Be Aware....!