Grouping of Phases in Compiler Design
A compiler is software that translates a high-level language into machine-understandable form. Typically, a compiler is made up of six states and the input code in high-level language also known as Source code passes through each state one by one, each state processes the code, resulting in machine-understandable code or object code as an output.
These six states of the compiler are further divided into phases on the basis of one-pass or two-pass compiler, the state is as follows:
- Lexical Analysis
- Syntax Analysis
- Semantic Analysis
- Intermediate Code Generation
- Code Optimization
- Code Generation
Phases in Compiler:
Generally, phases are divided into two parts:
1. Front End phases: The front end consists of those phases or parts of phases that are source language-dependent and target machine, independents. These generally consist of lexical analysis, semantic analysis, syntactic analysis, symbol table creation, and intermediate code generation. A little part of code optimization can also be included in the front-end part. The front-end part also includes the error handling that goes along with each of the phases.
2. Back End phases: The portions of compilers that depend on the target machine and do not depend on the source language are included in the back end. In the back end, code generation and necessary features of code optimization phases, along with error handling and symbol table operations are also included.
Passes in Compiler:
A pass is a component where parts of one or more phases of the compiler are combined when a compiler is implemented. A pass reads or scans the instructions of the source program or the output produced by the previous pass, which makes necessary transformation specified by its phases.
There are generally two types of passes
Several phases are grouped together to a pass so that it can read the input file and write an output file.
- One-Pass – In One-pass all the phases are grouped into one phase. The six phases are included here in one pass.
- Two-Pass – In Two-pass the phases are divided into two parts i.e. Analysis or Front End part of the compiler and the synthesis part or back end part of the compiler.
Purpose of One Pass Compiler
A one-pass compiler generates a structure of machine instructions as it looks like a stream of instructions and then sums up with machine address for these guidelines to a rundown of directions to be backpatched once the machine address for it is generated. It is used to pass the program for one time. Whenever the line source is handled, it is checked and the token is removed.
Purpose of Two-Pass Compiler
A two-pass compiler utilizes its first pass to go into its symbol table a rundown of identifiers along with the memory areas to which these identifiers relate. Then, at that point, a second pass replaces mnemonic operation codes by their machine language equivalent and replaced uses of identifiers by their machine address. In the second pass, the compiler can read the result document delivered by the first pass, assemble the syntactic tree and deliver the syntactical examination. The result of this stage is a record that contains the syntactical tree.
Reducing the Number of Passes
The various phases of the compiler have to be grouped for valid reasons: Grouping into a single phase makes the arrangement quicker as the compiler isn’t expected to move to various modules or phases to get the interaction introduction demand. Reducing the number of passes is inversely proportional as increases the time efficiency for reading from and writing to intermediate files can be diminished. While grouping phases into one pass, the whole program must be kept in memory to guarantee an appropriate data stream to each phase since one phase might require data in an unexpected request in comparison to the data delivered in the past phase. The internal portrayal of the source program or target program is different. Thus, the internal structure of the memory might be bigger than the input and outputs.