 Alright, so I think we should have a set up where I want to read the text that's on the screen, right? Okay, good. So this should be recording an audio and the visual right here, doing this extremely weird group voltage machine I have set up over here. So no promises that this is ever actually going to work, but at least we'll try. Okay, so, guys, so housekeeping stuff before we start. Homework two grades were posted earlier today. If you checked right when they were posted for some reason, there's a little bit, I don't know, check again, because we had a little bit of a weirdness that happened when we did the grading. The homework two solutions have been posted, so you should be able to see those. And I've also posted on Blackboard this exact practice exam. So you should be able to go look at it later and you can either follow along with what we're doing now to make sure you can do those same problems later, or kind of whatever you like. Yeah? Haven't there been two coding assignments? Have those grades been posted? One of the homework, project one has been graded, project two is still in the works because it needs the grading by hand where we're looking for various violations. So did you, three have remembered these mallocs, that kind of stuff, so a lot of them are great. Any other questions on class related stuff? Nope? Alright. Okay, so then we'll start at the beginning. Alright, so there's no guarantees that the mid-term is going to be exactly like this, but it will test obviously similar concepts and they'll be at hopefully similar difficulty levels. Okay, so the thing is you can't read that, you should let me know and I'll try to press buttons until something works. I have no idea if that's going to actually work. The first thing I'm here, read everything carefully, right? I feel like that should be kind of self-explanatory, but that's like general test-taking advice, right? Make sure you understand the question when it's asking. So you just read everything carefully because if you do the wrong thing, then you're going to lose points. So some statements can be tricky, it's not that they're intentionally tricky, we're not up here trying to get you, but things can be tricky, so make sure you understand what you're supposed to be doing, what you're supposed to be doing. Okay, can everybody read this? Can I zoom in a bit? That's a good question. Alright, how about now? Good? Okay, so problem one says, consider that we have the following seven regular expressions that are defined. So we have lowercase letter is defined as an a, a little a, a little b, a little c, or a little d. Uppercase capital letter, all capital letters are defined as either an uppercase a, an uppercase b, an uppercase c, or an uppercase d. We're defining digit here as five, six, seven, eight, or nine numerals. And then here we have, let's say four, maybe a combination of regular expressions here. So we have, okay, so a couple of things to notice. I'm using like a huge dot here. Anybody guess what that symbol means? It's a cat name. A cat name, right, yeah. If you just have the small dot, it ends up being incredibly small and really hard to read. If for some reason you have questions during the exam, it's not clear, raise your hand, ask. I may put something up here that just defines that, but it should be fairly straightforward that that's what that means. Okay, so we have alpha here, and alpha is going to be either, so we have a grouping here, right, with the parentheses. It's going to be either a capital letter or a digit or a question mark or an exclamation point. And it's going to be followed by another group, so another parentheses. It's going to be followed by a lowercase letter concatenated with a digit and star. So zero or more of letter, digit, letter, digit, letter, digit. So it has to be a letter followed by, a lowercase letter followed by a digit, but it can be zero or more of those, finally followed by an uppercase letter, yeah. In this case, we're using parentheses as grouping and not as actual characters that won't be represented. Like, not as actual symbols, right? So these are pretty much everything we've been talking about before, right? So these are all the same symbols and everything. If there's something special, we'd say that right. So if we tried to match a dot character, we would specifically say, hey, this slash dot means matches the character dot, it doesn't mean a regular expression. Yes, so the parentheses are just grouping. Okay, questions on the regular expression alpha? Checking five places. So now we hear you have the regular expression row, and row is a letter or a digit or a question mark or an exclamation point followed by a letter or a digit, any number, zero or more letters or digits, finally followed by a capital letter. Questions there? Then we have phi. Phi is going to be a capital letter or a digit or a question mark or an exclamation point followed by, now we have a grouping, right? So we have a grouping here that's followed by zero or more lowercase letters, followed by zero or more lowercase digits, and that happens zero or more times. Is it exactly the same thing as the one above it? Possibly, I don't know what you're telling me. And then we're ended here by a capital letter. Questions on that? Yeah. Where it might be the same, I can't figure out a counter-example. And you ask which is it in? You know if you give us a string, you say here are the rules. You just pick the first one, right? So, depends. So we'll look at it in a second, but yeah. So in the case that you have your parsing tokens from a string, right? And you have two things that match. If they match that entire input string in both the exact same length, then the precedence rule would apply. And so the ones that define the first would match. So that's a good point, right? So I don't know, can we prove that this does match, that this is identical? Maybe. But I guess the real question is if you do that and you're wrong and you treat them as they're equal and they're not, then you're going to mess up, right? So to me, you might as well just treat them as different things and then we'll see how it works out, right? If we're matching correctly, it should be fine. Okay, so this last one here, which everyone can see, good. So this last one here, omega is a digit followed by a letter, a question mark, or an exclamation point, followed by, once again, we have any number of letters followed by any number of digits, zero or more. All that zero or more times finally followed by an uppercase letter. So questions on the regular expressions, what they mean, what any of the operators are for me, that's going to be, I just get over on two copies. Okay. Okay, so now we're going to read the next question, right? So it says, for each of the following, fill in the blank with either, exists or is an element of or is not an element of. And so it's saying, recall that L of R for regular expression R is the language of R, right? So what are these questions asking us, like, semantically? Is, excuse whatever's on the left-hand side in the language on the right-hand side? Right, so remember we talked about a language, the language of alpha is the set of all strings that are described by this regular expression alpha. So we're saying, is this string, the string on the left, is it in that language or not? So how do we tell? Do we go generate this whole, all of these strings that are in this set? We're going to finish in time, right? You may not ever get to that string, but you could. But what's another way that this is, what's another thing that this is trying to ask us, semantically? Check whether what? Check the alpha, check one of it? The expression of alpha. The expression of alpha? So yeah, so the other way to look at this is, does this string match this regular expression, right? So if the string matches the regular expression, then this string can be generated by that regular expression, which means it's in this language alpha. So then the question is, does this string here, so capital A5, lower case A, capital A, is that a possible string that can be generated by alpha? No, so let's look at it. Okay, so we look first, we can see that, this is an A, so we know that it is a letter, right? So that matches, it's a letter digit, question mark or dollar sign. So we know that that matches, so we can move one over, and say, okay, the next one is a five, right? So is a five a letter? No, it's not. But we're going to start here, so this is zero or more. So maybe that meant zero. And then as we say, is a five a letter? No, so we would say, would we say that it exists or it not exists? It not exists. Or I guess we're good for that, more like that. Not too particular on here. Okay. Are you going to post the solutions to this as well? I will, possibly post, I'll probably post, maybe I'll scan these, but there should also be a video of it, so you can look at it. Okay, so for this next one row, so we're saying, is this same string, big A, five, big A, is that in this regular expression? So we have the letter here, right? The letter matches, then we go to the five, we say, is it a letter or digit? Yes. And then we say, okay, go to little A, is it also a letter or a digit? Yes. So then we say, okay, this next one, is it a letter or digit? No, it's not. But it is a capital letter, this letter, so it does exist in the languages for every row. Point on that. So then let's go over here. Okay, so now we have feet, so we have this other regular expression. We say, is this in there? So we have A, A matches the letter. We look at the five, we say, well it doesn't match a letter, right? It's not a letter, so that goes to zero. So then we look at this digit, it doesn't match a digit, yes. The next character, it's a little A. Does that match another digit here? No, it does not. But we have a star here, so we can do, match this again. So does it match one little, a little letter? Yes. Then we go to the next one, and it's a big letter, so it doesn't match the letter, right? So that doesn't repeat anymore. It doesn't match a digit, so that goes to zero. And it finally does match the letter at the end, so we can say that yes, this is in that language. I don't understand, because I thought concatenated, oh no, star implies a digit. Yes, exactly. Star implies a digit, so you can get it. Could it be easier? Yeah, and you kind of have to do it, whichever way makes sense to you. You can kind of look at all of these and say, well, it's got to be a letter at the end, right? Otherwise it's definitely not going to be in. So that you can look at. And then you can look at the beginnings, right? The beginnings are pretty easy. The trick is just all about the repetition. So how do you yourself handle that and go through that? All right, L omega, the language described by an omega. So here we have same strength. So we look at omega. We say, is this a digit? No. Oh, so it doesn't match. So we can stop there. Right, so then this one's pretty easy by the same logic, right? We can say it's got to start with a digit, otherwise it's never going to match an omega. Questions on those four? Yeah. There's no, there's nothing precedent here. All we're asking here is, is this string in the language described by this regular expression? So these regular expressions are essentially independent, right? I mean it's, so like for instance, this string here matches in both row and feet. But that's fine, because all we're talking about is matching. It would be a different question if we said if you have this string with the token, that's a return, right? It's a token we're thinking about all of the regular expressions at once. Yeah. Just to be clear, you can see that there was a language R in which all these regular expressions were encapsulated by any string matched to any of the regular expressions that would be a member of R. Yeah, so you could define a, let's say, if you really wanted to, you could define, yeah, we could call it R, and we could say it's alpha or row or C or omega, right? And so that would match any regular expression that matches any of those. So now we want to see, okay, we changed this string a little bit. We've added a six in the middle here. So how does that change things? So for alpha, we see, okay, the letter matches up, great. Okay, we don't have a letter as the next character, right? That's a digit. So this has to be zero, zero more repetitions, sorry, right here, zero more repetitions. And the next character is not a letter, so this is definitely not in that set. All right, and going down, looking at row, oh, and you can also see, so this is where you have to be very careful, right? So those have changed whether that matters or not, but I'm going to just, yeah. So if we see one instance of alpha inside this. What do you mean one set? Like, if you had AA in person, right? So then, as Anthony said, and then there's other stuff after AA, could we say that it's okay? So is the string, what are you saying, AA, and then something afterwards, like 2-3, or 1-2, or 1-2 is not even in there though. Let's say like AA-5. Could we say that's included, or alpha is included in there? So the way to think about it is, does, can this regular expression ever generate that string? No. Well, yeah. It can't generate this exact string, right? So it's got to end with a letter. Right. Right, so. But AA does not. That doesn't matter, right? Because that's like, it would be like, does AA match a letter? Well, it matches the first part, right? Right. I mean, it matches the very, and that's what we care about when talking about tokenizing, if you want to think about consuming the input. But here we're just talking about, so letter is only going to ever generate four strings, right? And all of like one, either single A, single B, single C, single B. And so those are the only four strings. So that defines the language of letters. And so when we're talking about here of matching, or here, like, does it exist in the language? The question is, can that regular expression generate that string? Like, is that in that language? And so the answer here is definitely no, right? You can't have that string in there. Just be clear, not exist. All right, so we're looking at row here. So we say, okay, the letter, got the letter. And we say, okay, we have a digit here. And so we repeat, okay, we've got another digit. And then we've got another letter. And then we say, okay, we have neither a letter or a digit. And so we're followed at the end by a capital letter. So then we say, yeah, that matches. That's going to be in the frame. Okay. So we have per fee, right? So we have a letter. So that matches. And we say, okay, letter. Well, this is in a letter. It's a digit. So that goes to zero. So we say, okay, yes, that matches the digit. It matches another digit. It doesn't match another digit. But we have a star here. So we're going to repeat again here. So I'm going to say it does this. Four is not a valid digit. It's not a recognized character. Oh. It's not a recognized character. Yeah, that's okay. So yeah, it definitely doesn't exist then. Okay, perfect. Two is correct. The next one is correct. We've already got an intro, right? I'm just making sure I don't pay attention. So there's a lot of teachable moments. All right. Cool. I didn't even need to. All right. So this one we've already done, right? So this one, Omega, that is the exact same one. We could also go through it again just to prove. Okay, good, good. See, it's like a freebie, right? So like, you know, maybe hope. Okay. So Alpha is good. So we look here. We see, okay, that matches a digit. That's number five. Then we see, okay. It's only matching a letter followed by a digit. So is this a letter? No, it is not. So that letter, so that doesn't match. So this has to be zero. There's a number of repetitions here in Alpha. And then so we say, was this five a capital letter? And the answer is definitely not. So it's not in there. All right, cool. Then we look at this, let's see, same string for row. So we have the digit. And then we go one more and we say, okay, here we've got a digit. Great. We can loop again with a digit. Great. We can loop again. Okay, we've got a lowercase letter. That's great. And then we've got a final capital letter. Awesome. So now we can say that that is definitely in that one. Then we have the same string in fee. So we have five matches the letter. Five matches zero of these letters. And one of these digits, two of these digits. The next character is a little a. It doesn't match the digit again, but we can repeat this. So I'm going to say it doesn't match a letter. Yes, it matches the letter once. And then we have a big a. It matches neither letter nor digit, but it matches capital letter. So it's definitely in there. Awesome. And now we have omega. So we have a digit. So it matches this digit. The next character is a letter. A question mark or an exclamation point. No, it's not. So this is not the next one. All right. Questions on any of those? You guys, do you got what? 8, 5, 10. Oh, 10. Wait, you just want to make up one? Wait, you're talking about this one? Oh, 4. It's not a digit. Very tricky. All right. So now let's bring it up. Okay. I already need more space. So where's the top of the string? There? Okay. So now this question is asking us, if we call getToken repeatedly on some input string until the end of input is reached, what the sequence of tokens returned is the following. So this is where we're specifically saying, assuming longest prefix matching is used and ties are broken in favor of tokens that appear first in the list. So that defines the precedence here and also defines that we're using longest prefix matching. So what does this look like? So what I'm going to do is I'm going to start by writing the string. So over here we're going to have five a, five big a, five five five, big a, little a, four fives, and a big e. And then I'm going to put the matching. And I'm going to put the possible, well maybe this is matched and this is like longest. Great. All right. So now I'm going to start parsing this. So now I'm going to say I look at five and so what matches five? Digit. Digit. Exactly. So this set is going to say digit. Does five match any of these other? It doesn't match any of the other ones but they're possible. Exactly. So that's the important point, right? So here in the matching column we want to keep track of what matches exactly like all the way through. Like that string that we've seen so far is in the language generated by that regular expression. And for right now that's only digit. It's only ever seen that digit matches now the possible ones, right? So this is a digit so it actually matches all of these. So we have, let's see, alpha, rho, p, omega. And the longest match up to this point is digit with length one, right? So we've seen that it matches there. Great. All right. Then we move on. We look at a. We consider five a. So does anything match five little a? Does digit match? Do I carry over digit? No. No, because it doesn't match. I don't want to match the strings with length one so it's gone. Maybe it helps to go through the possible. So now remember we don't have to go through all of these that are possible. We already calculated previously what regular expression we need to look at. So we look at alpha it does. So we have a digit and then we have here a letter which does match, right? That letter is an a. So that means that alpha is possible. Is it a match? No, because we haven't gone all the way through that string yet. So we look at fee. So fee matches the digit. And it's a letter or a digit. So that matches the letter here. So fee is possible. Sorry, row. We look at fee. Fee matches the digit. And then it matches one letter. So that's good. And then we look at omega. It matches the digit. And it matches the letter. So we still have omega. And we have nothing that matches yet. And I'm going to put this for the longest match. All right. This means whatever the moment. All right. So then we look at the next L end of the string. So we're looking at five. So we say, OK, it does. So we can create a matching set. We're not sure yet. So let's go through all these possibles. So we look at alpha, digit, letter, digit. So yes, alpha is in here still. So we look at row. We say digit, letter. And then back on again, a digit. Great. So we have definitely row. With fee, we have digit, letters, and then digits. So yeah, that still matches. It's possible to match. All right. Digit, letter, and a digit star here. So this star goes to zero. This one matches one. Nothing matches. We're still here. And we get to here to the A. Oh. I don't know that yet. OK. So I look at the alpha. I say does alpha match up to here? So we have digit, letter, digit. And then here we have a capital letter. So that matches here. So we actually match the whole string here. I can say alpha is matching. We're about row, digit, letter. So a letter match, loop again. The digit match loops again. There's a big letter that matches here. We have row. And then for fee, the digit, letter one, digit one, big letter doesn't match either of those so we can move on. So fee also matches. And find the omega. Digit, letter, letter zero, digit one, match one. Loop again now. Big letter so that matches. So all of them match? Are any of them possible more? No. Is there some yes or some no? It says yes. Yeah. Which can possibly match more if we put alpha where? This. Is that a good start? Remember this last A matches this last letter so we can't repeat that anymore. Otherwise we wouldn't be able to match it in here. All right. So none are possible. So which one is the longest matched? Alpha. Why? Because it's first in the precedence rule. So yeah, it's all the longest but we already know that since there's a tide here the precedence rule is going to go into effect. So it's going to say ties are broken, favorite tokens are going to be your first in the list. So that means we're going to have an alpha here with length of that one, two, three, four. And we have nothing more in our possible set, right? So there's no possible regular expressions that can match. So we know we're done here. We know we can say that this is our match and it's going to be this alpha, four. And then we're going to have the next part of the string. So we have, all right, so we have, let's see, five, five, five, A, a little A. All right. So I start by looking in here. We have a five. Does anything match the five? Digit. Digit. And possible, I suppose since we did this five up here we could probably copy this whole row that you could also work through it, right? The longest match right now is a digit with like one. All right. Now we're going to get the next character. So let's go through all the possibles. So alpha matches the digit and then does this match the letter here? No. No, which means this has to go to zero but does this five match the letter? No. Also no. So alpha is no longer possible. Alpha is no longer matching. So let me row. We have digit and then we have a digit. So that's still matching. That's so good. For phi we have a digit and then we have zero letters but we have digit here. We've matched that five so that's still in the process. And the omega digit and is this a letter? No. It's a digit. So it does not match omega. So now we only have two that are in contention row and phi. The longest one we've seen so far is a digit. As long as I get my extra paper. All right. So we are at this character here. We get this third five. So we say there's none matching in there. So what is possible? So we only have two, right? And now row and phi. So we just look here and say, okay, digit matches, digit matches. We can match a digit again. So row still matches. Phi, digit, digit again, digit again as many times as we want. So phi matches. So that's the longest. Now we're going to just dig A. And say, okay, just phi match that. We have a digit. Zero, a digit, a digit. Now we have a big A, which is a capital letter. So maybe try to loop this again. We can't. There's no letters in there. But it does match here. So we can put phi right there. Or we can put row right there. Can you move it up a little bit? Yes. That's a good question. Yeah. That's about where we're going. Yeah. All right. So row matches, right? Digit, digit, digit, big A. Phi, digit, zero, digit, digit, zero. Or I guess one if I want to do it once. And then big letter in here. And then so which one of these is the longest match? Which one do we put in here? Row or row? There we go. What was that? If row takes precedence, there's not really any point in looking at the next. Row takes precedence, but it could be possible that phi matches longer. So row could match first. Let's say if there was something after a letter, then phi would be able to match it. But like in this case? In this case, well, in this case, we don't actually know about what's going on here. These are the same or not. But yeah, we could prove that to ourselves that we can say whenever we see the phi in the row, we know that row is always going to be chosen. All right, so we have this is getting tokenized now. Now we have A. Cool. All right, we're going to do one more and then we're going to stop. We're going to have another problem. Okay, so what matches the little A letter, the lowercase letter? We'll say nothing does yet because we kind of couldn't tell. Okay, what else could potentially match? Can alpha? No. Row? No. Thieb? No. Omega? No. So nothing. So now we know there's no more potential matching here. So we know we're done. And we know that the token that's returned here is letter. So we know that's that. Up there. Okay. Oh, yeah. All right. So yeah, we've seen the A. So we know that the A, there's no more potential matching here. And then we stop. We know that that is the longest match. There's a letter of length one. So we return that and we continue parsing the rest of the string. So that's where we go. Continue doing this. But we're not going to do that right now. So I think we should get on to other questions so we can look at everything there. Any questions about what we've done so far? Yeah. How are we going to assume that there's like a some sort of erythrope in which you can put. Yes. So in that case we'll be able to put an erythrope in. Yeah, let's say that that would be put on there specifically. I may change that. Change it to a D because I can do that. We'll just have to go and rewrite this for you here. All right. Other questions? That's a good question. So let's say if we assume we go that's about that. Yeah, I mean there was another guy I should say. And it doesn't specify the question what to do in the case of an error that you should. But if you were doing that right, you'd try to parse up as far as you could through that error. And so you parse everything kind of up to there because nothing matches that E and then you would return error for the E but I would say that's not so important. So what are you looking for? What else is a possible match? Can you look at the first set of that? Wait, what do you mean? Is that a match here? I'm sorry, just when you're starting with this it's not possible. I mean possible? Like the possible sets? Yeah, I don't want to drop 200 in comparison because there are different things, right? We're calculating first sets on non-ternals in context-free grammars. Here we're talking about regular expression matching. So basically it's prefix matching. Like is the prefix that we've seen so far is that in the language described by this regular expression? So that's what we're looking for there. So if it's not going over done, we think it can't possibly be that match that token. Yes? On the test would be happening this table? It depends on how many points you want. So if you get it, I guess that's the biggest answer. What I mean is, so let's say I messed up here and here I returned digit mistakenly, right? So if I did that, I'd made one mistake and there'd be no way I would get this same sequence, right? Because it throws off everything else. So if you just put the right answer now, whatever, you can get full credit. I don't care. But if you make a mistake on this first one, it's going to cascade and you'll just get zero. As opposed to if you show your work, then we can verify, oh, you made a mistake here. But the rest of it is valid. So that way you can get partial credit for your answer. So I would say yes. And there'll be extra paper on your tank so you don't have to worry about bringing any questions. Other questions? Let's see if we can get to the other question. All right, that was problem one. All right, problem two. Consider the following grammar. Here's the grammar. I expect everyone can see what that grammar is. So the first question is, find a string with two different parse trees and draw the two parse trees. So what do we do? Just look at this really hard and try to make something up. But there's other techniques too. Yeah, so you look and try to understand so what are all the possibilities? Well, let's see, S is kind of interesting. It has two choices here. S can either go to A, B, C, D or just A. A can do A's on the left, C's on the right and any number of A's, A can also go to epsilon. B can go to little b, big b or epsilon. C can go to A, C or little c. So there's no epsilon and c. That's kind of interesting. D has to go to either big dA or little d which then is also interesting so there's no epsilon there just from kind of looking at it. So one way to do this, if you want to do this crazy, like you can just, you can peek ahead at the second thing and ask you to compute the first, that's the first of A and the follow of A. So you can actually compute those because if you can show that it doesn't have a predictive parser that could maybe help you figure out how to create that ambiguous parse tree. The other thing is we can start looking at parse trees and trying to think about what are the choices we have here and can we kind of force these strings to end up the same by choosing rules differently. So I think kind of one interesting thing is, okay I think to me these two are pretty interesting. Like we have S goes to A and S goes to A, B, C, D. So I try like an S goes to A so here I can kind of eyeball this and see I get an even number of A's followed by any order of C, D's, right, the same number. So I'm going to have some number of A's and some number of either C or D's on the right. So that could do C and this could go to epsilon, right. So this is one possible string in the language AC. So now the question is can I get, can I create the same parse tree by taking well different branches in the tree? So if you look at this, well clearly I can't because the only other option I have here is we put a D in the string here which that's not going to help anything. Then I look, okay well let's start at the very top and just kind of see what I can do to try to get as close as I can to the string. So I have S goes to A, B, C, D. Okay, so I have A here and I know well A can go to either AC or AD or nothing. Well that's going to mess me up. Well maybe it is, I don't know. I mean one way to try to match is we can go A, big A, little C and this goes to epsilon, right. Now the problem is we have to evaluate the rest here. So we can look and we can say well let's not worry about B's. Let's get rid of that. We'll look at a C and say well I'm either going to do an A or a C here and I have to choose something. So I can do like a C here for D I can do D. So here I have the string AC, CD. Here I have the string AC. Okay, so some things I can tell by looking at this, right? What are some things you guys can tell by looking at this? So that's what we've done here. What was what? There's a big experiment, I hope so. Why is this question doesn't make sense? From looking at this it seems like we'll have to, under the first parse tree blow up that middle layer a little more. You could look into the rules again in the first parse tree where A goes to add epsilon. Maybe that's a good place to get some more C's and B's in to match that second parse tree. Right, so one of the big challenges here if we look at just D, right? So D is either going to end with a little A or a D. Well if we want to kind of try to do the same strategy we're doing here there's no way if A, S goes to A there's no way A ends with a D or with a, sorry, with an A. Right, so you're going to end with a C or a D. And so maybe you're right maybe I choose this rule here and try different trees. S goes to A, A goes to maybe little A, D, A. So now I've matched these D's. I've got the C and then you could go I think some people are saying you could go A, C, A. Right, so you have a string A, A, C, D this goes to F1. So now I'm almost there, right? I have the A, but this set goes to a C. Right, where are we going? You could make that C go to AC and then make that first A go to F1. Yes, okay. Cool, okay so none of these work but we feel we're getting closer because we're understanding the grammar more. So we can say A, B, C, D. So we know A and B can go to epsilon so we're going to try and see if we can do a C here. So we know we want this D to match this D at the end, so we'll go D goes to D. And then this C in the middle, right, we could go A, big C, A, big C, and we'll see. And these go to epsilon, this goes to epsilon and we've got A, A. Oh, sorry, that's a small C. That actually looks so great. C, D. So the string I have is A, A, C, D. And so I've got the string and I've got the... So yeah, so I've got the string here so this is the string. So remember this is about, you've got to read the problem, right? Find a string with two different parsaries and draw the two part strings. Yeah, so you want to look at the grammar and try to understand what strings are going to be generated by the grammar. So you could try generating trees to see what that means to you. You can try looking at the rules and try to understand it. Yeah, those are all strategies. Yeah. What is a definitive strategy? How will we program this, I guess? I don't know. That's a good question. Well, it's okay. I don't know. Maybe... Yeah. I don't know. I thought my head was just kind of nice because it means it's more interesting when you calculate first the polysides, right? You have to come up with some intuitions. But it could be that there is, like one thing would be to generate all part strings, right? See if any of them generate two different strings, but I don't know if that would work. All right. Calculate first of S, first of A, and follow of A. Questions on what we're supposed to do here? S, A, C, D. 10 runs out of ink at exactly that time. Okay, so we first all initialize that into the empty set. So, with first sets now, what are we looking at? So we want to calculate first of S. Which of these rules are we looking at? The top two, why the top two? Again, with S on the left-hand side. We have S on the left-hand side, right? Exactly. So those are the ones we care about. So going through this once, we said, all right, we want to calculate the first of S. Well, in this rule, A is the left-most symbol. So whatever the first of S is, I'm going to add that minus epsilon to the first of, sorry, that's A. The first of A, whatever the first of A is, take that subtract that epsilon, add it to the first of S. There's nothing in the first of A, so that doesn't change anything. And then I say, well, do I move on and add the first of B? And I would only do that if there was an epsilon in first of A. And I look at first of A, there's nothing in there, so that rule doesn't apply. And the same logic with this example right here, it's the same thing, A. So I can say that that doesn't change S at all, which makes sense because it's kind of the first rule. I look at first of A, and so I add the left-most symbol, so I'm going to add the left-most symbol minus epsilon. So here the left-most symbol is little a, and what's the first set of little a? The second containing a, exactly. So we take epsilon out of there, it's not in there, so then we're going to add little a here. Do we go on? No, because there's no epsilon in the first set of little a. We go to the next rule, it also adds little a. We also don't go on. And then we hit the next rule and we see that, oh, a goes to epsilon, that means we add an epsilon to our set. And there's no more a rules, so we're done there. Then we look at B, we say we add little b. Do we go on? Nope, we're done here. And then we add epsilon. We look at C, we add a small a. Do we go on? Nope, don't go on. So then we go to the next one, we add a small c. And there's no more c rules. So we look at d, we say add the first set of d to d. What's the first set of d? Empty set. So we add the empty set in, it does nothing. We say can we move on? No. Because there's no epsilon in the first set of d. So we're done there, so we add the little d. Alright, are we done? Are these the first sets? Do it all over again. Is that right? Okay, now we look at S and we say, okay, let's look at this rule first. So add the first set of a, the left most simple, minus epsilon. So we add a here. Then we say do we move on to B? Yes. Because epsilon is in the first set of a. Right, so epsilon is in the first set of a, that means we add the first set of d minus epsilon. So we add d. And then we say do I move on and add the first set of c? Yes. Yes, if there is an epsilon in the first set of b, which there is, so I add the first set of c, which is a and c, so a is already in there. And then do I move on to d? No. No. So is there an epsilon in the first set of c? No. So if I move on, I'm done. Then I also, I'm copying S, so I also would go here and add the first set of a minus epsilon to S. So I take the first set of a minus epsilon to a, add an a. Then I say can I move on? Yes. No, there's nothing after it. Can't move on. But is there an epsilon in all of these symbols? Yes. Yes, so then I add epsilon to the first set of s. If a, the eyeball doesn't change, because it has non-terminals on the left, and the same for the rest of them, right? b, b, a, c. Well, let's look at d. Okay, so d, once again, we look and say, okay, add the first set of d to d. Well, it's little d. Great, that's already in there. Can we move on? No, can't move on. So then we don't add that a, we add a d, so that doesn't change either. All right, we're done. Do it one more time. Do it one more time. Well, maybe one more time. Or we do have to do it one more time. Let's go around this tree's letter. All right, so we have the s. We're going to add the first set of a to the first set of s, such as a. We're going to add, then we're going to move on to b. We're going to add the first set of b, minus epsilon, which is b. And we're going to add the first set of c, minus epsilon, which is ac. Then we're going to say, can we move on? The d, no. There's no c and first set of c. There's no epsilon and first set of c. Then there's s. This s, s goes to a. So we're going to add to a again. And then we also add to epsilon. So that didn't change. Good. a doesn't change. b doesn't change. c doesn't change. d doesn't change. We're good. What do we got? What are our first sets here? Questions on either of those? Yeah. So you have the first of b. What rule is that? But where? For the s. Sorry. s goes to a, b, c, d. Yes. So I add, so I apply rule three. So I add the first of a, minus epsilon, to the first of s. Because that's the correction rule. Yeah. Because that's rule three. Rule three says, always add the last most simple. And then the question is, do I move over one? Yes. And rule four says, I can add the next first set if there's an epsilon in the leftmost symbol's first set. So there's an epsilon in the first of a. So I can add the first of b minus epsilon to the first of s. Which is where I need to be from. And then I just do the same thing again. I say, does rule four apply again? Can I add c? I can if there's an epsilon in b. So I look at b. I say I have to leave an epsilon in it. So now I can add the first of c. So I add the first of c, even though there's no epsilon in there. Because this rule is equivalent to, because a and b can both go to epsilon, this is equivalent to there being a rule s goes to a, b, c, d. Or s goes to b, c, d. Or s goes to c, d. Because I know there's going to be some time where those go to epsilon. These rules are kind of implicit in the ground. So that's kind of why I'm thinking about it. The way that you finished off the first set of s is that instead of, isn't the proper way to do it, is actually just rewrite the set for that iteration and then go through updating the rules. It look like you just start off with an empty set on that very last iteration and you were just going through it. Yeah. Just one of those things I can't really show that it works exactly, but I'm pretty sure it does. I think it would. But yeah, you're copying this set over and then you're adding everything. Exactly. Yeah. So you can apply the rules and then copy or apply it, copy it over, and then start applying the rules. I mean, in terms of the project, that line messes up as the input has to be exact, like the output has to be the original. Is that what you're saying now? Because I think all of these values came from applying the rules to all of these. Because the sets are only growing. So here, you're adding all these values based on these other sets, and then later, if you start with nothing, you're using these same sets which have definitely the same values that they had before because you're only ever adding to them. So I think you can still create the same set. What if there was a weird rule where A, a first set was added, something was added to the first set of A, like down the line and you would... Yes. I don't understand. So you should just use the same set. The same set. Yeah. I'm a little confused. If C doesn't go to epsilon, where do you get an S? I mean, E before the epsilon and S. Oh, epsilon and S came from this rule. S goes to A. So A can go to epsilon, so that makes S can also go to epsilon. Yeah. Sorry, I'll ask the same question. The rule number four says E is an element of, like, say, A, B, that's not C. So basically, it will stop at B and then it would get added to the first set of C into the fifth defense. Seriously. I'm just kind of confused over where you added the first of B to S. So rule four says there's something before, all of the ones on the left-hand side, there's some C's, zero through whatever, they all have epsilon in their first set. In this case, A is that C, zero. There's only one. Yeah. And so we add B. We add the next one. We do C, I plus one, which is I in this case is... I plus one is B. So it just means to add the next one. And you can apply that iteratively, right? So we're going to apply it for when I equals, let's say, zero, where I equals one. When we look at one, so we add this one. And then we say, can I be two? Then we can also add C. So that's what we add C, but then we say, can I be three? No, because there's not an epsilon in these three first sets. All right. So we'll do one calculation of the following sets, and then I want to move on because we have other problems to cover. I think those are more important since there's stuff that we didn't have at home or not. Let's go to those. Want to go to those? Yeah. Can we just do those? Yeah. We'll do that when you come back in. Okay. Okay. This problem is about scoping, so... Okay. Consider the following code in C syntax. So we're declaring a global integer. We're declaring a function G that has no input and takes in returns nothing. We have a function F. We're declaring that declares a function I. Tab didn't really come out there. I'll fix that. We're declaring a new locally scoped I, setting I to three. Here we have in this block another I, setting I to two. We're calling G within this block, and outside that block we're calling G. In G, we take I, we add one to I, and then we print out the value of I for G colon space I. And the main function is that I to five, we call G, we call F, and we return zero. So the output of this program assuming static scoping, so the normal C execution, so you should verify that you know, right, how to do this. So the way I do this is I go through this program, and because I know statically I can match up based on the scope where exactly the references match to the decorations. So I can go here and say, okay, we have the global I. We have a local I, so I know this I corresponds to that I, right, because I can look out the scope statically and I can see, okay, got that maps here. And so I can look here and say, okay, this I maps to this I. So that's going to set that I to two. I can look here and say, okay, what does this I map to? This one? No. This one? This one? Yeah, so both, all three of these I's all refer to that global I. Because it's done statically, right, this is never going to change based on the execution of this function G. And then this I? Global. Global. Yeah. So then, if I want to know the outcome of the program, right, I can just trace through executing. So I'm going to keep here the value next to the declaration as to what that current value is. So here when this executes, right, it's going to set this global I to be five. And then G is going to execute. So we go into G, we say take I, add one to it, put it back. So it's now going to be six. Then we're going to print out I. So it's going to print out G colon six, and then a new one. Then it's going to, G is going to return. It's going to return here. Now we're going to call it to F. F's going to set this I to be three right here. Then we have a new block. We're setting this I to be two. We call to G. We go down here. What does this I refer to? The global, right? Static. It doesn't matter, right? So this is going to update it to seven. It's going to print out G on the seven. And now we have, we leave this block and we have another call to G. And now which one, so it's going to update this to be eight. It's going to print out G colon eight. And then this F is going to return. And that is going to return. And then May is going to return. So the output assuming static scope is G seven, or six, seven, eight. Except that's right. Except that's because it only matters how many times. Each time G is called, it's going to update the global I. So a static scope, meaning this binding of this name I here to the declaration is done statically at compile time. So it doesn't matter where G is called. All right. So now it's dynamic. So questions? Is this ever not a really terrible idea to do an actual coding? It can. So it depends. This is a short answer. There's sometimes where, like global where, so dynamic scoping is essentially every variable is global. It can be nice because you can allow functions that call you to change your behavior just by setting variables, which can be nice, but it makes it really difficult to reason about the behavior. No, I'm saying more specifically, like just only using one variable. Oh, exactly. No, of course not. But it doesn't demonstrate what we're trying to understand. I understand. Yeah. Okay. So the second part of this question is the output of this program is assuming dynamic scoping. So I'm going to go back up here so we can look at the whole thing. Then I'm going to put it here. Okay. What would the output be here? So I'm going to do the same thing again. I'm going to go simulate the execution, but I'm going to keep track here. I'm going to keep track of the current stack, the current symbol table. So when I'm executing the function, I first have this global i. And at this point, I really only care about i, like the variables. I don't care about the functions. There won't be any weird cases where functions change to new functions being called or locally defined functions. So i is being declared. It has no value. We get to main. Main sets i to be 5. So instead of statically knowing this, we look it up in our symbol table and we say, okay, setting the value of i to be 5. And then we call it to g. So we call it to g. g says increment the value in the i. So there's only one i that's been declared so far. So it has to be this one. And so we increment that to be 6. And we print it out. So we do g colon 6. This g returns. Now we call main calls f. So f gets called. Now this new block creates a new i in this block. And it sets this i. So that's i to be 3. So it looks it up in here. Okay, this is definitely 3. Then we enter this new block where a new i is declared. And we're setting that i to be 2. Now we call g. So we go down into g. g says increment i. So which i does this refer to? The last one. The one that has the value 2. So we're going to increment that. Put 3 in there. Print out 3. So we'll put g colon 3. Now this g returns. And so now we leave this. So this i, remember, has block level scoping. So this i is only valid in this block that it's declared in. It can be accessible by any functions that it calls that reference the main line. But once we leave this scope, now this i goes away. Now we call this g. So what's the value of the i? But this g has 3. Exactly. So this gets called. If you think of remember 4, if you call it 4. It's like a thinker method. And it returns. And then f returns. And then when the f returns, you do this. And it returns 0. So the output here is 6, 3, and 4. Questions on that? With the dynamic game statics, does the drawing of 4 does kind of like point significant of wrong? Is that what you're saying? If it was very clear about your thought process. Yeah, you would want to write more information about why. That's the problem is it's a dynamic process. So if you just have this, it'd be hard for you to get a partial credit on this because I don't really know what it means. If you mess up, it would depend on which i you are accessing at which time. So if you maybe label these and we're like this i goes away at this point or something like that. It'd be better to just get it right. Okay, so that's this question. Last question. Alright, problem 5. Consider the following Z code. So we have the two global int, star, stars, p and q. We have a main function. This main function declares an integer pointer a, and then new blockring, integer pointer b. We're mallocking a new int to point to a, and we're setting that equal to a. And so over here on the right, this is saying that that memory is a address. You can call it one. So that's what this comment means. It's when you need to put a value in somewhere you can call it one. Then we have b is equal to, we're mallocking a new integer for b. We're then doing star a is equal to 42. This comment defines a point in the program before we refer to you later. Then we were mallocking a new thing assigning it to b. So star b is equal to star a, and we're assigning p is equal to the address of a, q is equal to the address of b, and a new point. So we also have this assumption here, right? This is important. So assume all initialized pointers are equal to null. So if you had to draw a box, certain diagram, you would put null in the value of a pointer. So if I had a point, let's say this right here was point, point three, and I said, draw the box circle diagram for a and b at point three. Well, you have a bound to a box with a value, and the value in there is null. Same with b. Now, you normally can't assume this, but because we have this assumption here, this is what we need. Questions? So draw the box circle diagram for a and b at point one. So what's happened so far in the program? So a is... I didn't update this. This should be more complicated. Okay. a should be... a is going to have in its value. So, okay, first we know we have some a, some b, and we know that because they're declared here, right, they're bound to some location, and that location has a value. Okay. So here, at this memory allocation, what does mallop do in terms of box circle diagrams? And so it creates a location for us, right? So it creates a location somewhere which has, let's say, an uninitialized value. It doesn't really matter at this point. And what's the address of this location? Number one? Sure. Right? Because it specifically says it here. Okay. That's why. Normally you would have known you could use something symbolic but if it says it here, this is what, this is what this means. Okay. So then we have this assignment, right? So we're returning an r-value here from mallop which is the address of this location that it just created. And we're assigning that to a. So what are we doing there? Taking that r-value and copying it where? Into the value of the location associated with a. Right? So we take that, r-value that mallop returns is one. We're going to take that value, we're going to copy it into the location associated with a. So this is the location associated with a and the value in the location associated with a is the circle. So we take one and we copy it into the circle. Then we look at b and we do the similar thing. So we know mallop is going to create a new box which is a location with some value in it and so we know that it's going to be memory location two and by the same thing we know this assignment semantics is going to take two and copy it into the value of the location associated with b. The thing that's not on here. Okay. So then we get to here. So what is this semantics of this operation? 42. So what's 42? r-value or r-value? r-value. r-value, right? So it's just a value. So it's a total location associated with 42. So 42 is an r-value. So the semantics are copy that value which is 42. Copy it into the location associated with star a. So what's the location associated with star a? 1. 1. The location that has the address 1. So we copy that in there. So then we put 42 in here and wrap 0.1. So is there anything in here? We've got either null or nothing in there. That's either way is fine. So the other thing I didn't write here, let's say there was, if it was a, b, and it said label a star, b star, let's say with arrows. Right? So then you'd say, okay, I want to label a star. So where's a star? What's the address of the memory at a star? 1, right? I guess it should be star a. Okay, 1. Right? So then we're going to draw an arrow from the value inside of 1 to the box whose name is 1 and we're going to label a star a. And for b, same thing over here. Can you declare a and b? Yes. Considering b and q to be global instances, like, wouldn't that box diagram be represented as well? If I asked you to draw that, so like here I'm just saying, if you had to draw an a and b at this point, this is what you'd draw. If I wanted you to draw every, it should be very explicit. Like, I'm going to update these. So I want this one to be p, q, a, b, like star, b, star, q. Oh, that's fine. Yeah. Okay, so it is done. So the second question is how to draw this box level diagram for p, q and a and b. So you go through here all this execution. A big thing is in here. So you have to see that the new memory thing got that location 3. So you'll have a, b, b, q. In the late, you should probably just leave and then you can look at the video later. It's working. That's it. Can I what? I don't know. It looks like so much like yo. Okay. All right. Thanks here. We're maloc-ing a new piece of memory here. So maloc is creating a memory with address 3. And we're putting that address in b. So that's why 3 is in b now. So 2. This next line says whatever is in the value associated with star a, which in this case is 42, take that value and copy it into the location associated with star b, or copy it into the value of the location associated with star b. So star b, this box here, this location, and so this 42 gets copied over here to this 42. And then, so there is no, we don't have any addresses of an a right here so I'm using the address of operator here. You could give a and b symbolic values like x or y. I wouldn't have to keep memory 2. You wouldn't have to keep it floating down. The question is would you have to draw a box here or a series of things that you don't want to agree to just whatever is associated with it?