{"id":5,"date":"2018-07-19T09:44:20","date_gmt":"2018-07-19T09:44:20","guid":{"rendered":"http:\/\/csp10.epgpbooks.inflibnet.ac.in\/2018\/07\/19\/chapter-1\/"},"modified":"2018-07-24T05:19:19","modified_gmt":"2018-07-24T05:19:19","slug":"chapter-1","status":"publish","type":"chapter","link":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/chapter\/chapter-1\/","title":{"rendered":"Compiler Design"},"content":{"raw":"<div>\r\n\r\n&nbsp;\r\n\r\nObjective: To understand the processes involved in Compiler Design.\r\n\r\n&nbsp;\r\n\r\n<strong>1.\u00a0\u00a0\u00a0\u00a0 <\/strong><strong>Introduction :<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">This module starts with discussing the need for a Translator, Compiler. This module also tries to group the compiler into phases which will be discussed in the later part of this module. To begin, let us get to introduce a brief history of compilers.<\/p>\r\n&nbsp;\r\n\r\n<strong>1.1 A brief History.<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">In this Context, software can be defined as an essential component of the current scenario. Normally in earlier days software was written in assembly language. The instructions are written in Mnemonic code. For example, to add two numbers the following would be the assembly code.<\/p>\r\n&nbsp;\r\n<table class=\"aligncenter\" border=\"1\">\r\n<tbody>\r\n<tr>\r\n<td style=\"width: 489.063px\">MOV R1, a<\/td>\r\n<td style=\"width: 171.063px\"><\/td>\r\n<\/tr>\r\n<tr>\r\n<td style=\"width: 489.063px\">MOV R2, b<\/td>\r\n<td style=\"width: 171.063px\"><\/td>\r\n<\/tr>\r\n<tr>\r\n<td style=\"width: 489.063px\">ADD R1, R1, R2<\/td>\r\n<td style=\"width: 171.063px\">\u00e0 1.1<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n&nbsp;\r\n<p style=\"text-align: justify\">In statement (1.1), MOV is a command that would move the value stored in variable \u2018a\u2019 to register \u2018R1\u2019, \u2018b\u2019 to R2. The command ADD then adds the contents of the registers R1 and R2 and stores the result in R1. As one could observe, these instructions are closer to the machine than to the human. The drawbacks of writing programs in assembly instructions are:<\/p>\r\n&nbsp;\r\n\r\n\u2013\u00a0\u00a0 Very difficult to remember instructions\r\n\r\n\u2013 Benefits of reusing software on different CPUs became greater than the cost of designing compiler\r\n\r\n\u2013\u00a0\u00a0 Very cumbersome to write\r\n\r\n&nbsp;\r\n\r\nThese drawbacks trigger the need for software that will understand human language and that is the birth of Language Processors called translators.\r\n\r\n&nbsp;\r\n\r\n<strong>1.1.2. Language Processors<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">A <strong>translator<\/strong> is one that converts a <strong>source program<\/strong> written in one language to a <strong>target<\/strong> program in another language. This is similar to having a translator when two people who doesn\u2019t know the other person\u2019s language want to communicate. In the context of computer Science, a <strong>Source program<\/strong> is written in one programming language and a Target Program typically belongs to machine language. The Target language is called machine language as it is easier for the machine to understand. Some of the translators are As<strong>sembler, Compiler and Interpreter.<\/strong> Compiler converts programs written in high-\u00a0<span style=\"font-size: 1em;text-align: initial\">level programming language to assembly language. Assemblers convert assembly language programs to machine language (object language).<\/span><\/p>\r\n\r\n<\/div>\r\n<div>\r\n<p style=\"text-align: justify\">The translators help programmers to write programs in a language that is easier for them to remember and understand and converts them into a language that is closer to the machine. This results in the following ways of designing software:<\/p>\r\n&nbsp;\r\n\r\na.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Design an interpreter \/ translator to convert human language to machine language\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">The interpreter will have difficulties in parsing which may be ambiguous. For example, inefficient parsing would result in incorrect word boundaries during interpretation resulting in ambiguity.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">b.\u00a0\u00a0\u00a0\u00a0\u00a0 Design a compiler that will understand high level language which is not necessarily in English but closer to English and convert that to assembly language.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">The design is complex but parsing ambiguity could be avoided. The major drawback is the mapping of the high level language to assembly language. This also necessitates the designing a compiler for every high level programming language keeping in mind the instruction set of the target assembly language.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">c.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Design an assembler that converts assembly language to machine language The drawback of this is that the target language needs to be specified. Output of the various compilers to be known prior time<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">So, our aim is to design a Compiler and Assembler for converting high-level language to machine language. In addition, certain other things are need for pre-processing and execution which is discussed in the next section.<\/p>\r\n&nbsp;\r\n\r\n<strong>1.2 Language Processing System<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">A typical Language Processing system is given in Figure 1.1. The source program \u2013 program written in high-level programming language goes through a pre-processor. The pre-processor replaces macros and converts them into a complete code. For example, if we have a statement called #define MAX 100, in the source program, the pre-processor replaces MAX with 100 in all the places in the source program and passes it to the compiler. The compiler converts this to assembly language and the assembler converts to object language. At this point, the object language is called as the re-locatable object code. The code is re-locatable as it doesn\u2019t have the exact address of the memory at which this code is to be loaded for execution. This re-locatable machine code is passed on to the linker. The linker will link multiple source files into one or link the current source files with the object code of the standard library and gets one object file. This file is\u00a0\u00a0thenloaded\u00a0 \u00a0 into\u00a0 \u00a0 the\u00a0 \u00a0main\u00a0 \u00a0memory\u00a0 \u00a0 for\u00a0 \u00a0 \u00a0execution\u00a0 \u00a0 by\u00a0 \u00a0 \u00a0the\u00a0 \u00a0 loader<span style=\"text-align: initial;font-size: 1em\">.<\/span><\/p>\r\n\r\n<\/div>\r\n<img class=\"aligncenter wp-image-22 size-full\" src=\"http:\/\/csp10.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-e1532409505697.png\" alt=\"\" width=\"627\" height=\"837\" \/>\r\n\r\n&nbsp;\r\n\r\n<strong>1.2.1<\/strong>\u00a0\u00a0\u00a0\u00a0 <strong>Types of Code<\/strong>\r\n\r\n&nbsp;\r\n\r\nIn the process of generating assembly level code, the compiler could generate any one of the following types of codes:\r\n<ol>\r\n \t<li>Pure Machine Code: This refers to the set of Machine instruction which is independent of any operating system or library. These codes are typically available for the Operating Systems or Embedded Applications.<\/li>\r\n \t<li>Augmented Machine Code: They refer to the machine instruction that has operating system routines along with run-time support routines.<\/li>\r\n \t<li>Virtual Machine Code: These refer to the Virtual instructions that can be run on any architecture with a virtual machine interpreter or a just-in-time compiler. Ex: Java<\/li>\r\n<\/ol>\r\n&nbsp;\r\n\r\n<strong>1.2.2\u00a0\u00a0\u00a0 Work of a Compiler<\/strong>\r\n\r\n&nbsp;\r\n\r\nThe Compiler has to necessarily do the following to translate high-level source code to low-level assembly code\r\n<ul>\r\n \t<li>Processes source program<\/li>\r\n \t<li>Prompts errors in source program<\/li>\r\n \t<li>Recovers \/ Corrects the errors<\/li>\r\n \t<li>Produce assembly language program<\/li>\r\n<\/ul>\r\n<p style=\"text-align: justify\">After generating assembly language program, an assembler is used to convert the assembly language code into a relocatable machine code. The time of conversion from source program into object program is called compile time. The object program is executed at run time<\/p>\r\n&nbsp;\r\n\r\n<strong>1.3 Interpreter<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">An Interpreter is a language processor that executes the operation as specified in the source program. The inputs are supplied by the user. The interpreter processes an internal form of the source program and data at the same time (at run time) and therefore no object program is generated.<\/p>\r\n&nbsp;\r\n\r\n<strong>1.3.1 Compiler vs Interpreter<\/strong>\r\n\r\n&nbsp;\r\n\r\nThe following are some comparison between the compiler and the interpreter.\r\n<ul>\r\n \t<li>v For a compiler, a higher degree of machine independence exists and hence it facilitates high portability.<\/li>\r\n \t<li>v A compiler supports dynamic execution. This helps in making modification or addition to user programs even during execution.<\/li>\r\n \t<li>v A compiler also supports dynamic data type which helps in supporting the change in the type of object even during runtime<\/li>\r\n \t<li>v An Interpreter on the other hand requires no synthesis part.<\/li>\r\n \t<li>v Interpreter provides better diagnostics: more source text information available<\/li>\r\n \t<li>v The machine-language target program produced by a compiler is much faster than an interpreter at mapping input to output.<\/li>\r\n \t<li>v An interpreter is better with error diagnostics as it executes the source program statement by statement.<\/li>\r\n<\/ul>\r\n<strong>1.4 Compilation process<\/strong>\r\n\r\n&nbsp;\r\n\r\nThe process of Compilation and Interpretation is given in Figures 1.3 and 1.4 respectively.\r\n\r\n<img class=\"size-full wp-image-23 aligncenter\" src=\"http:\/\/csp10.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-1.png\" alt=\"\" width=\"916\" height=\"711\" \/>\r\n<p style=\"text-align: justify\">three As discussed, the compiler converts source program into relocatable object program, which then uses the data and executes in main memory on the other hand, the interpreter uses the source program and data and produces the execution without any intermediate object program.<\/p>\r\n&nbsp;\r\n\r\n<strong>1.4.1 Compiler<\/strong>\r\n\r\n&nbsp;\r\n\r\nThe compiler consists of two parts: Analysis and Synthesis.\r\n<ul>\r\n \t<li>- The analysis part breaks up the source program into constituent pieces and imposes a grammatical structure on them. It then uses this structure to create an intermediate representation of the source program.<\/li>\r\n \t<li>- The synthesis of its corresponding program: constructs the desired target program from the intermediate representation and the information in the symbol table.<\/li>\r\n<\/ul>\r\nThe <strong><em>analysis part<\/em><\/strong> is often called the <strong><em>front end<\/em><\/strong> of the compiler; the <strong><em>synthesis part<\/em><\/strong> is the <strong><em>back<\/em><\/strong> <strong><em>end<\/em><\/strong>.\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">The Front End of the Compiler is typically language dependent. It depends on the source language but it does not depend on the target machine\u2019s architecture. The Back End is target dependent as it requires the instruction set of the target machine but it doesn\u2019t require information of the source language.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">The Analysis and the Synthesis part of the Compiler is given in Figure 1.5. The Analysis part consists of components while the Synthesis part consists of two components Code Generation and Optimization. In the process, it uses Error Table and a Symbol table for the generation of target code.<\/p>\r\n&nbsp;\r\n\r\n<img class=\"aligncenter wp-image-24 size-full\" src=\"http:\/\/csp10.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-2-e1532409553726.png\" alt=\"\" width=\"521\" height=\"310\" \/>\r\n\r\n&nbsp;\r\n\r\n<strong>1.4.2 Compiler Passes<\/strong>\r\n\r\n&nbsp;\r\n\r\nThe grouping of the work of the compiler into analysis and synthesis part poses the following questions.\r\n<ul>\r\n \t<li>How many passes should the compiler go through?<\/li>\r\n \t<li>One for analysis and one for synthesis?<\/li>\r\n \t<li>One for each division of the analysis and synthesis?<\/li>\r\n<\/ul>\r\nTo answer all these questions, the work done by a compiler is grouped into phases which is discussed in the next section.\r\n\r\n&nbsp;\r\n\r\n<strong>1.4 Phases of the Compiler<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">The compiler\u2019s analysis and synthesis part is grouped into 6 phases and is shown in Figure 1.6. The first three phases belong to the analysis phase and the last three phases to the synthesis phase. All the phases of the compiler interacts with the symbol table and the error handler.<\/p>\r\n<img class=\"size-full wp-image-25 aligncenter\" src=\"http:\/\/csp10.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-3.png\" alt=\"\" width=\"598\" height=\"512\" \/>\r\n<div>\r\n<p style=\"text-align: justify\"><strong>Lexical Phase: <\/strong>Lexical analyzer reads the stream of characters from the source program and combines the characters into meaningful sequences called lexeme. For every lexeme, the lexer (lexical analyser) produces a token of the form which is passed to the next phase of the compiler.<span style=\"text-align: justify;font-size: 1em\">The token is of the form &lt;token-name, attribute-value&gt;, where token-name is an abstract symbol that is used during syntax analysis and an attribute-value: points to an entry in the symbol table for this token. During this phase, the symbol is created by the compiler, which has the information about the lexeme. The lexical <\/span>analyser<span style=\"text-align: justify;font-size: 1em\">, typically skips all blanks, unwanted white spaces and comment lines that <\/span>is<span style=\"text-align: justify;font-size: 1em\"> being available in the source program.<\/span><\/p>\r\n\r\n<\/div>\r\n<div>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\"><strong>Syntax Phase: <\/strong>The syntax phase of the compiler is the second phase. The phase is where the input from the source program is parsed and hence this phase is referred to as the Parser (parsing phase). The parser uses the tokens produced by the lexer to create a tree-like intermediate representation that verifies the grammatical structure of the sequence of tokens. A typical representation is a syntax tree in which each interior node represents an operation and the children of the node represent the arguments of the operation<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\"><strong>Semantic Phase: <\/strong>The semantic analyzer uses the output of the parser, which are the syntax tree and the information in the symbol table to check for semantic consistency in the source program. In this phase, the compiler gathers type information about the variables, operations, etc., and saves it in either the syntax tree or the symbol table, for subsequent use during intermediate-code generation. Type checking is done in this phase, where the compiler checks that each operator has matching operands. For example, typically an array index need to be an integer and the compiler must identify an error if a floating-point number is used to as an array index. Yet another job of the Semantic phase is type conversion, referred to as coercion. For example, a binary arithmetic operator may be applied to either a pair of integers or to a pair of floating-point numbers. If the operator is applied to a floating-point number and an integer, the compiler may convert or coerce the integer into a floating-point number.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\"><strong>Intermediate Code Generation: <\/strong>Compilers generate an explicit low-level or machine-like intermediate representation. This representation is necessary for generating assembly language. The characteristics of the intermediate representation are<\/p>\r\n&nbsp;\r\n\r\n\u2022\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Ease of Generation\r\n\r\n\u2022\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Ease of translation to target assembly language.\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">The input to this phase is the syntax tree and output is intermediate code. A convention for Intermediate code generation is the three address code. The three address code has at the most three operands and 2 operators. For example,<\/p>\r\n&nbsp;\r\n\r\nx = y <strong>op<\/strong> z\r\n\r\n&nbsp;\r\n<table class=\"aligncenter\" style=\"height: 42px\" border=\"1\" width=\"609\">\r\n<tbody>\r\n<tr style=\"height: 28px\">\r\n<td style=\"width: 374.063px;height: 28px\">x = <strong>op<\/strong> y<\/td>\r\n<td style=\"width: 286.063px;height: 28px\">\u00e0 (1.2)<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\nAs expressed in statement 1.2, x, y, z are three operands which are typically addresses and \u2018op\u2019 refers to the operator in addition to the \u2018=\u2019 operator.\r\n\r\n&nbsp;\r\n\r\n<strong>Code Optimization: <\/strong>This phase can operate either before or after code generation. The aim of his phase is to improve the intermediate code so that it results in better target code. This phase\u00a0<span style=\"text-align: justify;font-size: 1em\">also aims at generating faster, shorter code, so that target code is generated that consumes less power. The important characteristic of this phase is to carry out simple optimizations that significantly improve the running time of the target program without slowing down compilation<\/span>\r\n\r\n<\/div>\r\n&nbsp;\r\n<p style=\"text-align: justify\"><strong>Code Generation: <\/strong>This phase generation target assembly language. In this phase, the registers or memory locations are selected for each of the variables used by the program. The inputs to this phase which are the intermediate instructions are translated into sequences of machine instructions to complete an operation. One of the important consideration of code generation is the assignment of registers to hold variables as we have limited number of registers. This phase also need to decide on the choice of instructions involving registers, memory or a mix of the two.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\"><strong>Symbol Table: <\/strong>The symbol table is implemented as a data structure containing a record for each variable name, with fields for the attributes of the name. The symbol table is designed to help the compiler to identify and fetch the record for each name quickly. The symbol table has attributes that may provide information about the storage allocated for a name, its type, its scope. It also provides details on the function or procedure names, such things as the number and types of its arguments, the method of passing each argument and the return type.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\"><strong>Error Handler: <\/strong>The errors encountered in every phase are logged into the error handler for subsequent reporting to the user. The compiler however, recovers from the errors in every phase so that it can proceed with the compilation process. The compiler recovers from errors in either the panic mode of error recovery or phrase mode of error recovery.<\/p>\r\n&nbsp;\r\n\r\n<strong>Multi-pass Compiler: <\/strong>Several phases can be implemented as a single pass consist of reading an input file and writing an output file. A typical multi-pass compiler could do the following:\r\n\r\n&nbsp;\r\n<ul>\r\n \t<li>First pass: preprocessing, macro expansion<\/li>\r\n \t<li>Second pass: syntax-directed translation, IR code generation<\/li>\r\n \t<li>Third pass: optimization<\/li>\r\n \t<li>Last pass: target machine code generation<\/li>\r\n<\/ul>\r\n<strong>1.5 Summary<\/strong>\r\n\r\n&nbsp;\r\n\r\nThis module discussed need for a compiler and the various phases of the compiler.","rendered":"<div>\n<p>&nbsp;<\/p>\n<p>Objective: To understand the processes involved in Compiler Design.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.\u00a0\u00a0\u00a0\u00a0 <\/strong><strong>Introduction :<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">This module starts with discussing the need for a Translator, Compiler. This module also tries to group the compiler into phases which will be discussed in the later part of this module. To begin, let us get to introduce a brief history of compilers.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.1 A brief History.<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">In this Context, software can be defined as an essential component of the current scenario. Normally in earlier days software was written in assembly language. The instructions are written in Mnemonic code. For example, to add two numbers the following would be the assembly code.<\/p>\n<p>&nbsp;<\/p>\n<table class=\"aligncenter\">\n<tbody>\n<tr>\n<td style=\"width: 489.063px\">MOV R1, a<\/td>\n<td style=\"width: 171.063px\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 489.063px\">MOV R2, b<\/td>\n<td style=\"width: 171.063px\"><\/td>\n<\/tr>\n<tr>\n<td style=\"width: 489.063px\">ADD R1, R1, R2<\/td>\n<td style=\"width: 171.063px\">\u00e0 1.1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">In statement (1.1), MOV is a command that would move the value stored in variable \u2018a\u2019 to register \u2018R1\u2019, \u2018b\u2019 to R2. The command ADD then adds the contents of the registers R1 and R2 and stores the result in R1. As one could observe, these instructions are closer to the machine than to the human. The drawbacks of writing programs in assembly instructions are:<\/p>\n<p>&nbsp;<\/p>\n<p>\u2013\u00a0\u00a0 Very difficult to remember instructions<\/p>\n<p>\u2013 Benefits of reusing software on different CPUs became greater than the cost of designing compiler<\/p>\n<p>\u2013\u00a0\u00a0 Very cumbersome to write<\/p>\n<p>&nbsp;<\/p>\n<p>These drawbacks trigger the need for software that will understand human language and that is the birth of Language Processors called translators.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.1.2. Language Processors<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">A <strong>translator<\/strong> is one that converts a <strong>source program<\/strong> written in one language to a <strong>target<\/strong> program in another language. This is similar to having a translator when two people who doesn\u2019t know the other person\u2019s language want to communicate. In the context of computer Science, a <strong>Source program<\/strong> is written in one programming language and a Target Program typically belongs to machine language. The Target language is called machine language as it is easier for the machine to understand. Some of the translators are As<strong>sembler, Compiler and Interpreter.<\/strong> Compiler converts programs written in high-\u00a0<span style=\"font-size: 1em;text-align: initial\">level programming language to assembly language. Assemblers convert assembly language programs to machine language (object language).<\/span><\/p>\n<\/div>\n<div>\n<p style=\"text-align: justify\">The translators help programmers to write programs in a language that is easier for them to remember and understand and converts them into a language that is closer to the machine. This results in the following ways of designing software:<\/p>\n<p>&nbsp;<\/p>\n<p>a.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Design an interpreter \/ translator to convert human language to machine language<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The interpreter will have difficulties in parsing which may be ambiguous. For example, inefficient parsing would result in incorrect word boundaries during interpretation resulting in ambiguity.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">b.\u00a0\u00a0\u00a0\u00a0\u00a0 Design a compiler that will understand high level language which is not necessarily in English but closer to English and convert that to assembly language.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The design is complex but parsing ambiguity could be avoided. The major drawback is the mapping of the high level language to assembly language. This also necessitates the designing a compiler for every high level programming language keeping in mind the instruction set of the target assembly language.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">c.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Design an assembler that converts assembly language to machine language The drawback of this is that the target language needs to be specified. Output of the various compilers to be known prior time<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">So, our aim is to design a Compiler and Assembler for converting high-level language to machine language. In addition, certain other things are need for pre-processing and execution which is discussed in the next section.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.2 Language Processing System<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">A typical Language Processing system is given in Figure 1.1. The source program \u2013 program written in high-level programming language goes through a pre-processor. The pre-processor replaces macros and converts them into a complete code. For example, if we have a statement called #define MAX 100, in the source program, the pre-processor replaces MAX with 100 in all the places in the source program and passes it to the compiler. The compiler converts this to assembly language and the assembler converts to object language. At this point, the object language is called as the re-locatable object code. The code is re-locatable as it doesn\u2019t have the exact address of the memory at which this code is to be loaded for execution. This re-locatable machine code is passed on to the linker. The linker will link multiple source files into one or link the current source files with the object code of the standard library and gets one object file. This file is\u00a0\u00a0thenloaded\u00a0 \u00a0 into\u00a0 \u00a0 the\u00a0 \u00a0main\u00a0 \u00a0memory\u00a0 \u00a0 for\u00a0 \u00a0 \u00a0execution\u00a0 \u00a0 by\u00a0 \u00a0 \u00a0the\u00a0 \u00a0 loader<span style=\"text-align: initial;font-size: 1em\">.<\/span><\/p>\n<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-22 size-full\" src=\"http:\/\/csp10.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-e1532409505697.png\" alt=\"\" width=\"627\" height=\"837\" srcset=\"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-e1532409505697.png 627w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-e1532409505697-225x300.png 225w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-e1532409505697-65x87.png 65w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-e1532409505697-350x467.png 350w\" sizes=\"auto, (max-width: 627px) 100vw, 627px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.2.1<\/strong>\u00a0\u00a0\u00a0\u00a0 <strong>Types of Code<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>In the process of generating assembly level code, the compiler could generate any one of the following types of codes:<\/p>\n<ol>\n<li>Pure Machine Code: This refers to the set of Machine instruction which is independent of any operating system or library. These codes are typically available for the Operating Systems or Embedded Applications.<\/li>\n<li>Augmented Machine Code: They refer to the machine instruction that has operating system routines along with run-time support routines.<\/li>\n<li>Virtual Machine Code: These refer to the Virtual instructions that can be run on any architecture with a virtual machine interpreter or a just-in-time compiler. Ex: Java<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p><strong>1.2.2\u00a0\u00a0\u00a0 Work of a Compiler<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>The Compiler has to necessarily do the following to translate high-level source code to low-level assembly code<\/p>\n<ul>\n<li>Processes source program<\/li>\n<li>Prompts errors in source program<\/li>\n<li>Recovers \/ Corrects the errors<\/li>\n<li>Produce assembly language program<\/li>\n<\/ul>\n<p style=\"text-align: justify\">After generating assembly language program, an assembler is used to convert the assembly language code into a relocatable machine code. The time of conversion from source program into object program is called compile time. The object program is executed at run time<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.3 Interpreter<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">An Interpreter is a language processor that executes the operation as specified in the source program. The inputs are supplied by the user. The interpreter processes an internal form of the source program and data at the same time (at run time) and therefore no object program is generated.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.3.1 Compiler vs Interpreter<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>The following are some comparison between the compiler and the interpreter.<\/p>\n<ul>\n<li>v For a compiler, a higher degree of machine independence exists and hence it facilitates high portability.<\/li>\n<li>v A compiler supports dynamic execution. This helps in making modification or addition to user programs even during execution.<\/li>\n<li>v A compiler also supports dynamic data type which helps in supporting the change in the type of object even during runtime<\/li>\n<li>v An Interpreter on the other hand requires no synthesis part.<\/li>\n<li>v Interpreter provides better diagnostics: more source text information available<\/li>\n<li>v The machine-language target program produced by a compiler is much faster than an interpreter at mapping input to output.<\/li>\n<li>v An interpreter is better with error diagnostics as it executes the source program statement by statement.<\/li>\n<\/ul>\n<p><strong>1.4 Compilation process<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>The process of Compilation and Interpretation is given in Figures 1.3 and 1.4 respectively.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-23 aligncenter\" src=\"http:\/\/csp10.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-1.png\" alt=\"\" width=\"916\" height=\"711\" srcset=\"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-1.png 916w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-1-300x233.png 300w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-1-768x596.png 768w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-1-65x50.png 65w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-1-225x175.png 225w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-1-350x272.png 350w\" sizes=\"auto, (max-width: 916px) 100vw, 916px\" \/><\/p>\n<p style=\"text-align: justify\">three As discussed, the compiler converts source program into relocatable object program, which then uses the data and executes in main memory on the other hand, the interpreter uses the source program and data and produces the execution without any intermediate object program.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.4.1 Compiler<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>The compiler consists of two parts: Analysis and Synthesis.<\/p>\n<ul>\n<li>&#8211; The analysis part breaks up the source program into constituent pieces and imposes a grammatical structure on them. It then uses this structure to create an intermediate representation of the source program.<\/li>\n<li>&#8211; The synthesis of its corresponding program: constructs the desired target program from the intermediate representation and the information in the symbol table.<\/li>\n<\/ul>\n<p>The <strong><em>analysis part<\/em><\/strong> is often called the <strong><em>front end<\/em><\/strong> of the compiler; the <strong><em>synthesis part<\/em><\/strong> is the <strong><em>back<\/em><\/strong> <strong><em>end<\/em><\/strong>.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The Front End of the Compiler is typically language dependent. It depends on the source language but it does not depend on the target machine\u2019s architecture. The Back End is target dependent as it requires the instruction set of the target machine but it doesn\u2019t require information of the source language.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The Analysis and the Synthesis part of the Compiler is given in Figure 1.5. The Analysis part consists of components while the Synthesis part consists of two components Code Generation and Optimization. In the process, it uses Error Table and a Symbol table for the generation of target code.<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-24 size-full\" src=\"http:\/\/csp10.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-2-e1532409553726.png\" alt=\"\" width=\"521\" height=\"310\" srcset=\"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-2-e1532409553726.png 521w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-2-e1532409553726-300x179.png 300w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-2-e1532409553726-65x39.png 65w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-2-e1532409553726-225x134.png 225w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-2-e1532409553726-350x208.png 350w\" sizes=\"auto, (max-width: 521px) 100vw, 521px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.4.2 Compiler Passes<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>The grouping of the work of the compiler into analysis and synthesis part poses the following questions.<\/p>\n<ul>\n<li>How many passes should the compiler go through?<\/li>\n<li>One for analysis and one for synthesis?<\/li>\n<li>One for each division of the analysis and synthesis?<\/li>\n<\/ul>\n<p>To answer all these questions, the work done by a compiler is grouped into phases which is discussed in the next section.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1.4 Phases of the Compiler<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The compiler\u2019s analysis and synthesis part is grouped into 6 phases and is shown in Figure 1.6. The first three phases belong to the analysis phase and the last three phases to the synthesis phase. All the phases of the compiler interacts with the symbol table and the error handler.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-25 aligncenter\" src=\"http:\/\/csp10.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-3.png\" alt=\"\" width=\"598\" height=\"512\" srcset=\"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-3.png 598w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-3-300x257.png 300w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-3-65x56.png 65w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-3-225x193.png 225w, https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-content\/uploads\/sites\/50\/2018\/07\/Untitled-3-350x300.png 350w\" sizes=\"auto, (max-width: 598px) 100vw, 598px\" \/><\/p>\n<div>\n<p style=\"text-align: justify\"><strong>Lexical Phase: <\/strong>Lexical analyzer reads the stream of characters from the source program and combines the characters into meaningful sequences called lexeme. For every lexeme, the lexer (lexical analyser) produces a token of the form which is passed to the next phase of the compiler.<span style=\"text-align: justify;font-size: 1em\">The token is of the form &lt;token-name, attribute-value&gt;, where token-name is an abstract symbol that is used during syntax analysis and an attribute-value: points to an entry in the symbol table for this token. During this phase, the symbol is created by the compiler, which has the information about the lexeme. The lexical <\/span>analyser<span style=\"text-align: justify;font-size: 1em\">, typically skips all blanks, unwanted white spaces and comment lines that <\/span>is<span style=\"text-align: justify;font-size: 1em\"> being available in the source program.<\/span><\/p>\n<\/div>\n<div>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><strong>Syntax Phase: <\/strong>The syntax phase of the compiler is the second phase. The phase is where the input from the source program is parsed and hence this phase is referred to as the Parser (parsing phase). The parser uses the tokens produced by the lexer to create a tree-like intermediate representation that verifies the grammatical structure of the sequence of tokens. A typical representation is a syntax tree in which each interior node represents an operation and the children of the node represent the arguments of the operation<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><strong>Semantic Phase: <\/strong>The semantic analyzer uses the output of the parser, which are the syntax tree and the information in the symbol table to check for semantic consistency in the source program. In this phase, the compiler gathers type information about the variables, operations, etc., and saves it in either the syntax tree or the symbol table, for subsequent use during intermediate-code generation. Type checking is done in this phase, where the compiler checks that each operator has matching operands. For example, typically an array index need to be an integer and the compiler must identify an error if a floating-point number is used to as an array index. Yet another job of the Semantic phase is type conversion, referred to as coercion. For example, a binary arithmetic operator may be applied to either a pair of integers or to a pair of floating-point numbers. If the operator is applied to a floating-point number and an integer, the compiler may convert or coerce the integer into a floating-point number.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><strong>Intermediate Code Generation: <\/strong>Compilers generate an explicit low-level or machine-like intermediate representation. This representation is necessary for generating assembly language. The characteristics of the intermediate representation are<\/p>\n<p>&nbsp;<\/p>\n<p>\u2022\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Ease of Generation<\/p>\n<p>\u2022\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Ease of translation to target assembly language.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The input to this phase is the syntax tree and output is intermediate code. A convention for Intermediate code generation is the three address code. The three address code has at the most three operands and 2 operators. For example,<\/p>\n<p>&nbsp;<\/p>\n<p>x = y <strong>op<\/strong> z<\/p>\n<p>&nbsp;<\/p>\n<table class=\"aligncenter\" style=\"height: 42px; width: 609px;\">\n<tbody>\n<tr style=\"height: 28px\">\n<td style=\"width: 374.063px;height: 28px\">x = <strong>op<\/strong> y<\/td>\n<td style=\"width: 286.063px;height: 28px\">\u00e0 (1.2)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>As expressed in statement 1.2, x, y, z are three operands which are typically addresses and \u2018op\u2019 refers to the operator in addition to the \u2018=\u2019 operator.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Code Optimization: <\/strong>This phase can operate either before or after code generation. The aim of his phase is to improve the intermediate code so that it results in better target code. This phase\u00a0<span style=\"text-align: justify;font-size: 1em\">also aims at generating faster, shorter code, so that target code is generated that consumes less power. The important characteristic of this phase is to carry out simple optimizations that significantly improve the running time of the target program without slowing down compilation<\/span><\/p>\n<\/div>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><strong>Code Generation: <\/strong>This phase generation target assembly language. In this phase, the registers or memory locations are selected for each of the variables used by the program. The inputs to this phase which are the intermediate instructions are translated into sequences of machine instructions to complete an operation. One of the important consideration of code generation is the assignment of registers to hold variables as we have limited number of registers. This phase also need to decide on the choice of instructions involving registers, memory or a mix of the two.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><strong>Symbol Table: <\/strong>The symbol table is implemented as a data structure containing a record for each variable name, with fields for the attributes of the name. The symbol table is designed to help the compiler to identify and fetch the record for each name quickly. The symbol table has attributes that may provide information about the storage allocated for a name, its type, its scope. It also provides details on the function or procedure names, such things as the number and types of its arguments, the method of passing each argument and the return type.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><strong>Error Handler: <\/strong>The errors encountered in every phase are logged into the error handler for subsequent reporting to the user. The compiler however, recovers from the errors in every phase so that it can proceed with the compilation process. The compiler recovers from errors in either the panic mode of error recovery or phrase mode of error recovery.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Multi-pass Compiler: <\/strong>Several phases can be implemented as a single pass consist of reading an input file and writing an output file. A typical multi-pass compiler could do the following:<\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>First pass: preprocessing, macro expansion<\/li>\n<li>Second pass: syntax-directed translation, IR code generation<\/li>\n<li>Third pass: optimization<\/li>\n<li>Last pass: target machine code generation<\/li>\n<\/ul>\n<p><strong>1.5 Summary<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>This module discussed need for a compiler and the various phases of the compiler.<\/p>\n","protected":false},"author":4,"menu_order":1,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":["dr-t-v-geetha"],"pb_section_license":""},"chapter-type":[47],"contributor":[58],"license":[],"class_list":["post-5","chapter","type-chapter","status-publish","hentry","chapter-type-standard","contributor-dr-t-v-geetha"],"part":3,"_links":{"self":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/pressbooks\/v2\/chapters\/5","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/wp\/v2\/users\/4"}],"version-history":[{"count":5,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/pressbooks\/v2\/chapters\/5\/revisions"}],"predecessor-version":[{"id":346,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/pressbooks\/v2\/chapters\/5\/revisions\/346"}],"part":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/pressbooks\/v2\/parts\/3"}],"metadata":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/pressbooks\/v2\/chapters\/5\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/wp\/v2\/media?parent=5"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/pressbooks\/v2\/chapter-type?post=5"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/wp\/v2\/contributor?post=5"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp10\/wp-json\/wp\/v2\/license?post=5"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}