.

(Vn U Vt)*
we define First(
) to be the set of terminals that
might appear as the first symbol in a string derived from
. First(
) will include
if
. Thus,
First() = { a
Vt |
![]()
a
, for some
( Vn U Vt )* } U {
if
![]()
![]()
}
).
(Vt U Vn)
First( x )FirstSet[ x ]
} for all nullable
non-terminals and to { } for all other non-terminals.
t
add
t to FirstSet[ N ].
,
write
as
= 
'
where
is a string of nullable non-terminals,
and
' is either the
or a string of terminals
and non-terminals beginning with a non-nullable symbol we will
call M.

'

, add
(FirstSet[ x ] -
) to FirstSet[ N ].
' =
then
add
to
FirstSet[ N ] otherwise add
(FirstSet[ M ] -
) to FirstSet[ N ].
S A B C
A a | CB
B C | A d |
![]()
C f |
![]()
- All the non-terminals are nullable:
- B and C are directly nullable.
- The production A
B C, then implies A is nullable.
- Then, the production S
A B C implies S is nullable.
- The productions break down as:
![]()
![]()
S ![]()
A B C A ![]()
a A ![]()
CB B ![]()
C B ![]()
A d B ![]()
![]()
C ![]()
f C ![]()
![]()
- The FirstSet values start out as shown in the table below and can be refined by iterating over the production table.
S A B C a d f { }
{ , a }
{ }
{ , f }
{ a } { d } { f } { } { } { } { } { a } { d } { f } { }
{ } { } { } { a } { d } { f } { }
{ } { } { } { a } { d } { f }
Follow( N ) = { xVt | A
![]()
N x
} U {
if S
![]()
N }
Mthen Follow(N) must contains First(![]()
N
) . If
is nullable, then Follow(N) must also
contain Follow(M). These observations are enough to give us
an approximation algorithm for computing Follow. See the books
on reserve for details.