When I took the compiler course in college, I did not understand FIRST and FOLLOWS at all. I implemented the algorithms described in the Dragon book, but I had no idea what was going on. I think now I'm doing it.
I assume that you have a book that gives a formal definition of these two sets, and the book is completely incomprehensible. I will try to give them an unofficial description, and I hope this helps you understand what is in your book.
The FIRST set is a set of terminals that you can see as the first part of a non-terminal extension. The FOLLOWS suite is a collection of terminals that you might see after expanding a nonterminal.
There are only three types of terminals in your first grammar: = , * and id . (You can also consider $ , the end-of-entry character, as a terminal.) The only non-terminals are S (operator) and L (Lvalue is a “thing” that you can assign).
Think of FIRST (S) as a set of non-terminals that could run an instruction. Intuitively, you know that you are not starting the expression with = . So you did not expect this to appear in FIRST (S).
So how does the instruction begin? There are two production rules that determine what S looks like, and both begin with L So, to understand that in FIRST (S), you really need to look at that in FIRST (L). There are two production rules that determine what an Lvalue looks like: it either starts with * or with id . So FIRST (S) = FIRST (L) = { * , id }.
SHOULD (S) be easy. Nothing follows S , because it is a symbol of the beginning. So, the only thing in FOLLOWS (S) is $ , the character of the end of the input.
FOLLOWS (L) is a bit trickier. You should look at each production rule where L appears and see what happens after it. In the first rule, you see that = can follow L So, = is in FOLLOWS (L). But you also noticed in this rule that there is another L at the end of the production rule. So, one more thing that could follow L is all that could follow this production. We have already found out that the only thing that can follow S products is the end of the input. So FOLLOWS (L) = { = , $ }. (If you look at other production rules, L always appears at the end of them, so you just get $ from them.)
Take a look at Easy Explanation and for now ignore anything related to ϵ because you don’t have ones that contain an empty string. In the "Rules for the first sets" section, rules No. 1, No. 3 and No. 4.1 should make sense. In the section "Rules for subsequent sets", rules No. 1, No. 2 and No. 3 should make sense.
Everything becomes more complicated if you have ϵ in your production rules. Suppose you have something like this:
D -> SCT id = V // Declaration is [Static] [Const] Type id = Value S -> static | ϵ // The 'static' keyword is optional C -> const | ϵ // The 'const' keyword is optional T -> int | float // The Type is mandatory and is either 'int' or 'float' V -> ... // The Value gets complicated, not important here.
Now, if you want to calculate FIRST (D), you cannot just look at FIRST (S) because S can be "empty". You intuitively know that FIRST (D) is { static , const , int , float }. This intuition is encoded in rule # 4.2. Think of SCT in this example as Y1Y2Y3 in the Simple Explain rules.
If you want to calculate FOLLOWS (S), you cannot just look at FIRST (C) because it may be empty, so you also need to look at FIRST (T). So FOLLOWS (S) = { const , int , float }. You will get this by applying the "Rules for the following sets" # 2 and No. 4 (more or less).
I hope this helps and that you can find FIRST and FOLLOWS for the second grammar yourself.
If that helps, R represents an Rvalue - a thing you cannot assign, such as a constant or a literal. An Lvalue can also act as an Rvalue (but not vice versa).
a = 2;