Welcome back, In this video we're going to
talk about converting regular expressions
into non-deterministic finite automata.
Before we get started I wanna give you an
overview of the plan for the next few
videos. We have a lexical specification
that we want to implement and the first
step is for someone to write that down as
a set of regular expressions. Now that
bites all the courses not implementation,
that's just specification. So we have to
translate that into a program that can
actually do lexical analysis and this
actually happens in several steps. The
first part is a translate Those regular
expressions into non-deterministic finite
automata that recognize the same, exactly
the same thing. And then those
non-deterministic automata are translated
into deterministic automata and finally
those deterministic automata are
implemented as a set of Lookup tables and
a little bit of code for traversing those
tables. So in previous videos, we talked
about this piece and we've also defined
this piece. And so now we're ready to put
the whole thing together and in this
particular video, we're going to focus on
this component right here, The translation
of regular expressions to
non-deterministic finite automata. So the
plan is that for each kind of regular
expression we're going to find an
equivalent Non-deterministic Automata,
automaton that accepts exactly the same
language as the language or a regular
expression. And here's a little bit of
notation we're gonna use. We'll define
these automaton for regular expressions
and usually, what we're going to be doing
is needing to modify their start states
and their final states so we'll just
indicate the start state with the l and
the final state. With the double circle
and we won't worry too much about the
overall structure of the machine as long
as we have a handle on the start state and
the final state. I should say that in the
machines we'll build here, there will only
be one final state. Okay, so let's begin.
So for the epsilon regular expression,
once the machine that accepts that, well
this is a very simple machine. We can just
have a start state and a final state and
epsilon transition between them so this
machine accepts exactly the empty string.
Certainly for a single character A, we can
define a one transition two state machine
that accepts that one character. So from
the start state we can move to the final
state if it only, if we read that
particular character, okay. So those are
out two simple regular expressions and now
we have to do the compound regular
expressions. And these are little
[inaudible] involved. So let's talk about
concatenation first. And so, because we're
gonna build these machines up from
smaller. Regular expressions to larger
ones, we can assume that we've already
converted A and B separately in two
machines. So I have the machine for A. And
to have a machine for B and now all I have
to do is say how I'm going to paste
together these two machines to form a
machine, a compound machine that
recognizes the same language as a
concatenated with B. And here's the
construction, the start state for the
compound machine will be the start state
for A so we'll just keep that start state
for A the same and then we modify the
final state of A. So we make the final
state of A no longer a final state and
I've done that here by removing the double
circle on the final state of A andthe
epsilon transition to the start state of
B. Now if we think about it, that does
exactly the right thing but that says, is
that first you recognize some portion of
the input that belongs to the language of
A, and when we get to that, what would
been the final state of A, we can jump to
the start state of B without consuming any
input and then try to read the rest of the
string as part of the language, as, as a
string in the language of B. And for union
we have a similar way of phasing together
the machines. Although the, the structure
is somewhat different so we, at a new
start state for the compound machine and
What does A + B mean? It means either the
input is in the language of A, or it's in
the language of B. And epsilon transitions
are really good for capturing this because
we just make a decision right from the
start state is the string going to be in
language of A or is it going to be in the
language of B. So we make a
non-deterministic choice and then we read
the string as using that, the automaton
that we chose and if we get to the final
state. Either those machines we can make
the epsilon transition to the new final
state for the compound machine. Now
remember what the notion is of acceptance
for Nondeterministic Automata, you know?
They make these guesses but if there's any
guess that works, then we say that it's in
the language of the machine. So, if in
fact the string is in the union of A or B
then either choosing A or choosing B will
work and so the machine will accept the
string. And finally the most complicated
case for iteration is star, we have the
following construction, So here's the
machine for A, Embedded in here. We've
added a new start state and a new final
state, And now, let's talk about how this
works. So one possibility, if we remember
that epsilon is always in the language of
A, and so we have this transition here,
We can go straight from the start state to
the final state and accept the empty
string. And so, that just guarantees that
the empty string is in the language.
Otherwise, what do we do? Otherwise, we
can make a transition, an epsilon
transition to the start state of A. And
then we can, from the final state of A if
we reach it, we can go back to the start
state of the whole machine and we can do
this as many times as we like. Okay, So,
there's the iteration of A, Surround this
loop right here, And when we reach the
final state of A we can also decide to
just make a transition to the final state
of the machine, we conclude that the last
time. And so this machine recognizes zero
or more strings in the language of A. So
now, let's do an example, So here's a
regular expression and we want to build a
equivalent nondeterministic machine that
recognizes the sa me language and we're
gonna follow our construction, Which works
by induction on the structure of the
regular expressions starting with the
simple regular expressions and building up
to the compound one so what do we have
here? So we have a machine for accepting
one, okay. So we need a machine that
accepts one and if we call it had two
states and it just, you know made a
transition between the two on the number
one, Similarly a machine for accepting
zero. Okay, And now, we need to put them
together in a machine that accepts either
one or zero. And the way we did that is we
made a choice from A, from a start state
for the compound machine where you can
either move to the machine for accepting
one or the machine for accepting zero. And
then we have, at the end, also epsilon
moves back to the final state of the
compound machine. Okay, And now we need to
iterate this so we need to be able to
accept zero or more of one's or zero's and
so we're going to take this entire Block
here and paste it into the pattern that we
had for iteration so how do we do that?
Well, we have a new start state and a new
final state, okay. And there's an epsilon
move from the start state to the new final
state to guarantee that we accept the
empty string. And then we can just iterate
this inner machine as many times as we
like. We can make an epsilon move to the
start state, We could execute the machine
ones and if we decide we want to do it
again, well we can do that. Okay, Go back
around for another time, Or from the final
state, we can decide that we've seen
enough and we can just move to the final
state of the compound machine. So this
machine then accepts the language one +
zero. And now, we have a little bit more
to do. We have to accept, we have other
machine that accepts just one so we build
another machine that accepts The digit one
and now we need to compose two of these
things, to concatenate them and that was
very simple. We just have an epsilon move
from the final state of the first machine
to the start state of the second mac hine
and then these are all the states of the
final machine. And we just need to now
label our final, final state or the end of
the state that we're actually gonna use in
the end of the final state of the entire
machine which should be that one and the
start state, Which is this state over
here. And that's the entire construction
for the non-deterministic automata or a
non-deterministic automata that recognizes
this language.