 So, we generate here this code and the technique we are going to do this is the same which is the translation. And what we have to do now is that as I process a rule which is a grammar rule of this form I simultaneously want to generate code for this state. So, first let us understand how we are going to generate code for this and I will introduce now few more attributes for this and again I am going to use subscript which is like the relationship between e and e 1 and e 2 so that these are same inputs but we have different properties. So, one thing I would like to know now is that if you recall the way we were generating this code when I wrote something like this and suppose I say a is assigned x plus y plus z we want to write here this code for this we were generating some certain temporary. So, we said e 1 is doing the x plus y and e 2 is going to be e 1 plus z and then a is going to be assigned. So, as I am going through this process of parsing simultaneously I am going to write this code for the two things we need to understand here. One that if you look at these variables e 1 and e 2 these are temporary variables which have been generated by this file. So, that means I must have some function which can generate now a temporary name for me this is one thing you have to remember. Second thing that when I parse this particular string which is x plus y I am going to put it in a temporary name and then I am going to parse this and this together then I am going to put that value into another temporary name. That means I must remember where each of these expressions is being stored. So, that is the temporary name I must remember and therefore I must also have some attribute for otherwise I will not be able to get this code. And the next thing I have to do is that I must remember what are the code sequences I have generated so far. Because finally I am generating code and I am saying this is the code corresponding to this. So, I must remember what is the code sequence for this what is the code sequence for this and then what is the code sequence of this and what is the code sequence corresponding to this. So, I must also have some attribute for code anything else I need to have any other information I require for generating code other than these attributes and this point of time it is like that as far as script and code is concerned I do not require anything else. Now, assuming that I have all these attributes available to me then what are the type of code I will generate for this. So, let us with all these attributes and this example let us see that if I just have the grammar rule like this and I am reducing by the right hand side and I am reducing it to be what kind of rules I need any ideas. Let us look at what we have written here. Once again we are able to do it then we will be able to see that generalizing is going to be much easier. So, what are the code sequence for this. So, let us look at this code sequence. Now, as I said so first thing I must remember is that I have some attribute which is saying that I must remember where e1 is stored and where e2 is stored some place. So, that means I have some attribute which says e1 place and some attribute which says e2 place which will give me name of the variables which says that where expression corresponding to e1 has been stored and expression corresponding to e2 has been stored. Next thing I will have to do is once I know these places I will have to get a temporary name corresponding to this and say that these two variables are added and stored in that particular location. So, the way I can write my code is I can say that e place is a new term. So, suppose I make a function called without any argument which says that e place is going to be stored into the temporary name I have generated and then I will say that what is the code corresponding to e. So, if I look at the complete code sequence corresponding to this particular t. So, look at a parse tree like this that I have some nodes which are hanging like this this is how my parse tree is going to be. So, now if I say what is the code corresponding to e or will I write that attitude and so if I say it is e1 code very good compacted with e2 code anything else I need to do. So, I must generate now one instruction which will say that do this addition. So, that means the next instruction is going to be that I am going to now generate which will say that e place is e1 place plus e2 place. So, first thing I said was I am going to generate a temporary name and then I am going to say that I am going to have e code which is same as e1 code followed by e2 code followed by generating a new instruction it is saying that e place is assigned e1 place. Now, what happens here? So, look at this once again that now suppose I am parsing x and y. Then if I just parse this sub expression using this rule what will happen first thing I will say is a new temp corresponding to e. So, what will be the new temp it will generate t1 and then it will generate an instruction saying e1 code and e2 code. Now, what is e1 code and e2 code when I am just parsing this nothing it is just a variable. So, no code has been generated and then I will generate this instruction which will say t1 is assigned e1 place and where is e1 that is in x and what is e2 that is in y. So, I end up generating an instruction which will say that t1 is assigned x plus y and that value will be stored in e code. Now, when I parse this whole thing again I will say that I generated new temp. So, I generate t2 and then I will say e1 code now what is code corresponding to this that code is the instruction I just generated and what is the code corresponding to this null and then I will generate one more instruction that will say t2 is assigned t1 plus z. So, it will generate these two instructions in the right side. Similarly, if I want to write now rule for saying that I have a statement. So, if I say that my rule is something like this that it is assigned in expression then what is the kind of code sequence I will get here for this null. So, let us look at this and try to write rule for this particular grammar tool set. So, I am not trying to figure out what my s code is and do I need a place for s? Do I need a place attribute for s? I do not require any place because that is the statement that is the final thing. So, what is my s code in this case? Give me rules now that you have all the examples in front of you. So, how will s code look? So, all I need to say is this is e code concreted with one more instruction I need to generate model that one more instruction I need to generate I need to generate which will say that id place is assigned. So, now if you see the third instruction which has been generated that will be passed by this particular rule e has already been passed value of that is already stored in p2. So, I will generate the last instruction to say that id places this and e code is already stored these two instructions which is even being assigned x plus y has to be assigned p1 plus z that is already available. Will I get all the information here? Yes? No. Now, suppose I write a new rule which says e goes to e star e. So, I am now changing my operator if I change the operator then what will I get? So, I am not telling you what of the rooms I will write for this. It is same as the first one except that operator will change from addition to addition. There is no other difference. So, is it making sense now? Or we are generating free address code? So, let us now go through once we have understood this part. Let us go through the generation of free address code. This is how the code will look that if I am saying. So, we are already familiar with what free address code is. So, I am not repeating that part. So, when I have grammar rule which says id is assigned e then I am saying s code is nothing but e code followed by this instruction. And if I have a rule which says e goes to e1 plus e2 that means I am taking two expressions and adding them. Then I will say that first I have to make it all to new tab to generate a temporary where this expression will be stored and then I will say e code is nothing but e1 code followed by e2 code followed by generating an instruction. And if I say I have multiplication then it will be repeated except that this plus will get replaced by multiplication. Clear? Are you confident now that given this straight line expressions or any kind of expressions with no control flow no loop nothing I can at least write systematically free address code. Now let us add few more rules. So, now suppose I have a rule like saying that e is a practical expression. What are the attribute expressions for this? So, e code is equal to. So, let us change this. So, what will I write? I have two attributes which I have to generate and four. So, what will be e code and what will be e place in terms of e1 attributes? So, e code will be just e1 code and e place will be e1 case. And what about this? So, I have to generate another instruction first or I just can carry all the instructions are generated so far and that will be sufficient. I need to generate one more instruction. That means if I need to generate one more instruction that means I need now a new tab. So, first thing I will say is that e place is a new tab and then I will say that e code is e1 code followed by a new instruction which will say that e place is minus e1 case. So, you will be negation. So, this is how my code will look. e place is new tab and e code is e1 code followed by generation of new instruction to say e case is minus e1. So, this is how we can just take on all the expressions now. So, you can see that I have taken care of all the assignments. I have taken care of all the arithmetic operators. You need to just elaborate it on all possible operators and then I can do it on negation. And then I can do it for bracketed expression and I can do it for id. And in case of id I am not taking any code but I am just taking the case value. So, all expressions are done. For all expressions now I can write here this code. Okay, expressions which involve arithmetic operators. So, here is an example and if we try to write it. Now, suppose I am just parsing it. I am not trying to use that but I am not trying to even optimize number of calories that we will get some other point of time. Maybe later. Okay, suppose I need to now code for this by parsing all the rules. What is the kind of code I will end up generating? First, you can see that if I am scanning my input from left to right, a assignment will be generated and then first this univc will have to be taken because this has a higher incidence. Okay, so this will have the highest incidence then the multiplication will come and this b star minus c will be evaluated. This b star minus c will be evaluated and then addition will happen and then assignment will happen. So I will end up generating code like p1 is being assigned minus c and then p2 is being assigned b star p1. So that gives me value of this sub expression. I need to do the same thing here. So as I said I am not optimizing calories here at this point of time. So I will now say p3 is minus c and p4 is b star p3 which gives me value of this sub expression. Then I need to add the two and put that in a new temporary to say p5 is p2 plus p4 and then I say a is assigned to p1. That is the kind of free address code I end up generating for this particular expression. Clear? Any questions on this? So this looks fairly straightforward as far as generation of free address code for expressions is concerned. Any complexity which is involved, something which is not clear, anything because this is something you are going to heavily used in all your colleagues. You need to do code generation and you need to understand all these things. Now let's come to flow of control. So if straight line expressions are clear then I need to worry about flow of control. Now what are the flow of control statements I have? I have if, I have if then else and then I will introduce hydration. But let's see first conditionals. Now to generate code for conditionals only thing I need to understand is that what is the semantics of each of the statements. So for example if I say a rule which is of this form. Suppose I have a statement which says if expression then statement. Say it is possible. So again I want to distinguish between this as on the left and that is on the right because they have different attributes. And E is a Boolean expression. And for this for the timing what I am going to assume is that I have some type of a basic code Boolean expression. I will not worry about how do I do that. I will take that as a black box for the timing. But only thing I need to remember is that when code for this has been generated. What is the place where this value has been stored? Because I need to go and compare. So when I say place what that means is there is some category in which value of Boolean expression has been stored. And then I need to compare that for true or false. So how is code for this look? Seventically what does it mean? Seventically what it means is that first I will give it code for E. Then I will check whether this is true or false. If this is true then I will go and execute this code. And if this is false then I will jump to some level which is beginning of the next statement. So now only way only thing I need to know is therefore not worry about code for can be systematically generated. If you know the semantics of this particular statement then very easily do that. So first you will say is that I have some E code that has to be generated. So let me write straight away S code. So this is what my S code is going to be that first I must have code for E. Now once I have code for E then what is the next thing I need to do? I must check it for true or false. Now where is the value of this E code stored? That is in E place. So now I need to generate one instruction which will say that if E place is equal to E place is equal to true then what will happen? Then code for S1. So can I do it other way round and say that if this is false then where do I go? After S1. After S1. And what is that after S1? I need to have a label where I can jump. That means now I need one more function. Earlier I was generating only 10 degrees now I also need to generate labels. So now let me say that I also generate labels so let me say that L1 is a new label and new label is some function I have introduced which will give me a full of labels we keep saying that there is a label. So now I will say that let's jump to L1 but if this value is true then what do I do? Then I go and execute S1 code. Now assuming that S1 is straight line code it has no control flow but even if it has control flow for this and all I need to say is that this is S1 code. And after that what do I need to do? I need to generate a label. After all that is where the control is going to be so I need to now generate one more instruction and I will say that generate now L1 this label. Does it semantically translate what I have captured here? So this is really what happens in control of code. I started actually with a different example so since I started with by example let's also work that out or let me skip that part and first go to so I started with identification bit. Let me skip this part. So here is if that is actually a more general case of if that is if that is. Now two statements here one is S1 and another is S2 and depending on whether this value is true or false I will either execute S1 or S2 now how this code which I have just shown and this code these two things are going to be different. Don't tell me the difference everything else will be that if I say that if this is true then depending on that I will either jump on this or jump on this now depending on whether you compare it to 0 or 1 one will be a false true statement another will be a jump. So you need to have one more level for either than or as part depending upon whether you compare this with 0 or 1 say that if this is false then I am going to a level which is corresponding to as part which is S2 and if otherwise it will just fall through and execute S1 I don't require a label for that and if S1 gets executed then where should I just fall through or jump somewhere then I jump to a label which is after S and then I will say I have a label which is corresponding to S else where I jump here and then I have for S2 and then what do I have I have one more instruction for jump no it will just fall through right so then I will have this only for S after then somebody for some reason this is not displaying colors as it should so this is how this schema will look and if I now say that this is how the schema is looking then there are two labels which are being generated and I need to make calls to these two labels so what are these labels these are I will say that S else is now a new label and S after is a new label so these are two new labels and then I will say S code is nothing but E code followed by this statement if you say that if E place is 0 then I jump to this label then I will have code corresponding to S1 then I generate now one more instruction say jump to S after then I generate this label and then I will generate code for S2 and then I will generate this label S after so this takes care of both so when we are generating code after so whatever statement will after that won't be repeating that in the first when we generate code for that statement so what will you repeat good question but what will you repeat I am only getting a label not a full state now you are still not completely your question or you are not actually it is an issue which you are sort of raised but you are not so what happens okay so let me rephrase the question now what happens if the statement immediately after this has a label in the beginning what will happen in that case so suppose so let me go back and just wait for one slide and then we will discuss this okay so let's go back to what we just skipped and which was okay and then I will address this issue which just states okay now how do I generate code for file statement now okay what is what is the schema what is the schema what is the schema what is the schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema what is schema to this and then I will have a label SR and if I now write it in terms of code, how will it look? It will look something like saying that I must generate a new label corresponding to this and I must generate another label corresponding to this. So, two labels must be generated and then I will say that S code is now just this schema which is generating a label begin then it has code for E. So, I still do not know how to expand the code for E, but I am assuming that this part has already been processed. So, when we look at Boolean expressions this part will become clear and then I generate this instruction which says if E place is 0 then I jump to S after and then I have code corresponding to S 1 and then I have code which is corresponding to this jump and then I have generation of label itself. Now, suppose after if there is a statement next statement is why? So, I am generating one label in if there is a statement which says go to the beginning of the next statement and I am generating another label which is part of this while which is taking me to the beginning. So, what happens is if there is a followed by why? You have two labels of the beginning of a while statement actually yes we will have two labels right. So, if there is a statement will generate a label, but when control comes to this label there is no executable corresponding to that. So, it will fall to the next label that will work, but that is very inefficient we do not want to waste number of labels. Another issue is that when we are talking of labels suppose I need to generate machine code and not assembly code. See if you are generating assembly code then labels are nothing but symbolic labels you have done assembler you have read something about assembler yes no. So, how do I determine suppose I am assembling this program I am using machine code how do I find out address of the label. So, if I say here go to S after what is this address go to S after do I know this address at this point of time. If I am not using symbolic name, but suppose I am assembling this this is now assembly code and I say jump to S after what is the PC value of S after do I know it at this point of time yes no why do I not know it what prevents me from knowing it at this point of time. I do not know how much code is involved in S 1 by its recursive definition. So, when I am passing this I do not know how many instructions are going to be taken here. So, when I say I have to repeat in the beginning of every class please turn off your mobile phones and so on within that an industrial protocol when you enter a class So, if I do not know the address of this when do I fill in this address I will know this address only after I have generated all this code these are PC values. That means what will happen is that this place will have to be that actually blank that you will not fill in this and this will be filled in afterwards after I have determined value of this label and we are going to use a technique called back patching. So, if I am using back patching then you will find that this problem of multiple labels but in this key when I am not doing back patching it is a two pass assembly or two pass code generation then I will generate all kind of clearance. Is your question now answered. So, these are two flow of control statements we have that we can handle while now I am not going to do repeat until and so on because once you have understood schema for one iteration rest of the iterations are going to be the application of the same thing and once you have understood schema for if then else then all conditioners are going to be same except one which is case statement which I will handle slightly different because case statements are special and they are not just if then else. Now, what will happen is that in the simple table I am putting names now. So, two instructions earlier which I had generated I will now modify it and say that when I was so first when I wrote this and I said e quote is nothing but id place. How do I know what my id places I have already entered that in simple table. So, I will just I can do a look up and find out that what this id places. So, basically this is returning a pointer. So, if I am just saying return a pointer to this I do not have to have a name for this and a pointer will be sufficient and we say that if this is not null that means this value has already been entered in the simple table then I am going to emit this particular quote. If it is null that means variable does not exist in the simple table then I am going to give an error. Similarly, when I say e goes to id. So, these are the two places where I need to access my simple table e goes to id all I need to do is look up this id and if this id has not null then I say e places p otherwise this is an error. So, this is the only additional thing I need to do now need to check whether this value is already in the simple table because I do not know when I start parsing the value cannot be there at all. Now, next thing that comes is arrays. So, I have handled simple variables but what happens in arrays? Array have certain properties which are different than variables and one property is arrays have is that all array elements are going to be given consecutive locations. That means when I write something like. So, if I have a declaration like in grade 10 what this means is are two things one that I am going to now allocate 10 elements which are going to be indexed by 0 to 9 if I am talking of c and depending on language the index values may change but more importantly I will say that I am now reserving certain space in memory which will have 10 locations 3, 7 and 3. So, this is going to be a 0, a 1, 2, 3, 4, 5, 6, 7, 8, 9. These 10 locations are being reserved. So, I will not say that a 0 is. So, my map is not going to be something like saying if this is my memory that a 0 is here then a 1 comes here and then a 2 comes here. This is not what is used. I always have consecutive locations. Now, if I have consecutive locations for all array elements in memory then do I need to know the addresses of each of these variables? I do not have only thing I need to know is that what is my base address from where the storage starts and what is my index value? These two are sufficient to find out. So, in symbol table I am only going to store the base address and whenever I say that I am trying to access a i only thing I need to know is i and I need to know my base address and then I can do this computation. Now, this part of this computation has to be pre-computed and stored in the symbol table for code generation. So, what will happen is that arrays are going to be stored in a block of consecutive locations which are like this and assume that bit of each element is done. That means from the type information I know that how many bytes each of these elements is taken. So, if I say this is an integer array and each integer is given 4 bytes then I know that it is taken 40 bytes. That gives me the total address which is required. Now, when I say that I want to find ith element all this is saying is that I need to know my base address plus I need to know what is the lower index. Now, depending on the language it could be 0, it could be 1 or their languages which will say that which will permit me to have declarations which will say a is 10 to 90 that is also permit. So, giving you a more general expression and which is saying that I must know the lower index value. So, if I know I and I know the lower index value then ith element can be found by saying take the base address find out the difference and multiply it better. Now, you can see clearly that if it is 0 then the base address. So, for example, if I want to know the base address of I then I just need to have 9 here and this will just vanish. So, this will give me 36 base plus 36. So, that is what will happen that which is the relevant native address of A. So, depending on the language you will have to find what your low value is and if I now take this expression and sort of do some library and reorganize it. You can see that there is a constant part which is base minus low into W and there is a part which is dependent on I and I can write it in this form. Now, this constant base minus low into W this can be pre computed and can also be stored in this interface. I do not have to compute it every time. If I say that I want to find out A I or address of A I I do not have to compute this part and I can just access this because then only thing I need to compute is this particular multiplication and this addition. That is going to save me again time it is going to be getting more efficient. Now, if I go to two-dimension arrays problem becomes slightly more complex and then we generalize it for two-dimension arrays. So, if I go for two-dimension arrays and I say that I have now. So, let us not worry about languages like C where arrays are going to be handled by pointers. But let us take a situation like this and I say that there are two-dimension arrays which is going to be mapped out to memory. First question that comes is that if this is my array, how do I map it on to? What is the order in which I am going to pick up elements from this particular array? What is the order in which I will pick up? Can I randomly pick up these? Obviously, no. Then do I go in this direction or I go in this direction? And why in this direction? It is defined by the language. So, either you are going to have row major storage or you are going to have column major storage. Fortress has a column major storage. C has a row major. So, if you take a Fortin array, that is how it is going to be stored. So, this is called column major and row major is going to be that I will take elements in this direction and will keep the storage. Now, obviously, you can see that access patterns are going to be different because I am not assuming square arrays. These two dimensions could be different. So, access pattern depending upon whether this is row major or column major is going to be there. That means I will still start with my base address here and suppose I say that I want to access this particular element which is aij. Now, to find out aij, that means if this is giving me the row number and this is giving me the column number, I need to find out how many rows are before that and multiply that by number of elements and then that will take me to this base address. Then I say that how many columns are previous to that. Then that is the computation I need to do to find out the base address of aij. So, this is what happens. The storage can either be row major or column major depending upon the language you have. In case of 2D array stored in row major, for column major you can do this computation. The address of ai1, ai2 or aij can be calculated in this form. It says that base address of aij can be calculated in this form. So, this is what happens when I say that this is giving me the row number minus whatever is the low index of ai multiplied by number of elements in each row, which means number of columns are. So, you have to see very clearly that when I am saying I am computing this, I will say how many rows are before that and multiply that by number of columns. So, n2 gives me number of columns are and i2 minus low 2, which is giving me then this offset and multiply whole thing by w and what is the number of points each element is going to take and add that to the base address. State expression again I can reorganize this. So, n2 is just giving me column numbers and if I rewrite this expression, this is how this expression will look and you can see that this part of the expression is constant and this part is the only one which depends upon i1 and i2. So, after simplification you can see that this expression can be pre-computed and can also be stored in the symbol table. So, this is I will say that this is a constant part constant value which is part of the symbol table. So, to find out the address of ai1 i2, this is the expression I like to compute everything. This is the kind of code I like to generate. So, if I now say that and this you can now expand to all n dimensions and also you can expand it to that instead of row measure if I have column measure then you just need to change this particular expression. So, there is doable I mean there is simple 6, 7 class. So, as code generation what we will do that if I say that a some array which is 10 by 20 and I want to find out. So, n1 is 10 elements and 2 are 20 elements and I assume that w is 4 which means each element takes 4 bytes and I want to access a y z. So, y and z are 2 indices this is how my code will look. I will say that d1 is y star 20. So, this is basically this part is the one which corresponds to computation of y and z and this part is t3 when I say t3 this is really computing this constant. So, I do not know what this a is this a will be and then I know this a. So, when will I know this a at what point of time this a is computed or is known to me. So, whenever I say that array a is going to be stored in some memory then I will know the base address of a and that also is in the symbol table. So, I can then just compute this part and then I can add and generate code. So, you can see that expression is not being computed every time I am writing code for a y z then the only change. So, there is a 3 address code for computing arrays. So, only difference between a variable and array is going to be that arrays are going to have consecutive locations and therefore given an index value you will have to find address of each of the address for all other variables addresses in the symbol table. Any questions on this? So, now let us look at one more thing and if you recall at some point of time we started doing type checking and type coercion. And when we are doing type coercion at that point of time I wrote code in certain manner. So, if you recall I said that when we have code in this form and then I said if this is in and this is in then type of this is in and if this is float and this is float and type of this is float and if this is in and this is float then I wrote one expression by doing a kind of type internal type coercion. So, same thing now in terms of code generation what will happen there if I am now trying to generate code and I say mixing of types is allowed that means e 1 and e 2 could be of different types but they obviously need to be valid types as far as this expression is concerned. Then the way I have to generate code is now if e type is integer and e 2 type is integer then I am going to emit code which will say that e place is now assigned e 1 place plus integer addition and e 2 place and type is going to be integer. So, now you can see that I am mixing type checking along with the code generation. And this is the reason if you recall I said that rather than clubbing it in just two clauses we are saying if both are integer then this is integer else this is real. I am going to mix this into four separate cases. So, this is what happens here and similarly if both are real then the same thing can be done but if two are not the same one is integer and another is real then what will happen then I will have to do type casting which is internal coercion. So, what do I do now for type casting now you can see that if this is integer and this is real that means even has to be type casted to now real. So, for this I now need a new temporary variable and I say that I am going to emit now a code which will say that u is assigned into real which is the function to type cast e 1 place. So, this interior has now been type casted to real and then I will say that e place is nothing but u and real addition and e 2 place. So, one more instruction for type casting has to be now and then I will say e type is real or what will happen when this is real and this is integer I just need to flip the order here and say that it will be e 1 place and u will be into real of e 2 place. So, I just need to change the order and I will get similar source code from this. So, now you can see that when it comes to real type getting in code generation it is not sufficient to say that I will generate 2 clauses but I need to expand it in full 4 clauses and for each case I need to get in the code and this is also ensuring that I am generating the right kind of operation here. So, in this case I will generate integer addition and in this case I will generate real addition and in all other cases actually I will generate real addition. But in this case I am also generating now an implicit type casting instruction. Sir, if we are going to separate table there is a similar which is more general type this is the for example there is a but it is not a real . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . So, if I am only, as I said my language is assuming that e 1 and e 2 are only a 5 integer and real. Now, suppose you say that I can convert an integer to character and I need an expression. So, that is the restriction which is imposed by the language, not by the compiler. The compiler is just implementing whatever language is saying. So, if my language says I am only allowed to mix imp in real, then I am doing this. If you say that I am allowed to mix all these tantiles, then I just need to expand all these cases. That is the only thing I do. So, let us take a break there today and all those who did not collect their answers in the previous class. You can just start. I have my telephone here. Thank you.