For a context-free grammar G over Σ = {0, 1, 2}, with start variable S:
S → 0S0 | 1S1 | 2S2 | Y
Y → 22
How do i turn this into an equivalent Push-Down automaton
For a context-free grammar G over Σ = {0, 1, 2}, with start variable S:
S → 0S0 | 1S1 | 2S2 | Y
Y → 22
How do i turn this into an equivalent Push-Down automaton
A pushdown automaton can push symbols on top of a stack and pop them off. It can also base its transitions on the topmost stack symbol. We need to think of a mechanism that will allow us accept the right language by manipulating our stack.
The language your grammar generates has the following characteristics:
22
in the middle{0, 1, 2}
. That is, it reads the same forwards as backwards.We need to "remember" the beginning of the string so that we're able to tell whether the end of the string is being repeated backwards. This is a good use case for a stack: we can push the symbols onto the stack as we see them, and then pop them off as we're reading them back. One other note: we know we can only try to start reading back after reading 22
.
First, we read everything and push it onto the stack until we find "22":
Q s S Q' S'
----------------------
// read 0s and 1s and push them on the stack
q0 0 Z q0 0Z
q0 0 0 q0 00
q0 0 1 q0 01
q0 1 Z q0 1Z
q0 1 0 q0 10
q0 1 1 q0 11
// if you read a 2, pus it on the stack and
// go to a new state where we look for a second 2
q0 2 Z q1 2Z
q0 2 0 q1 20
q0 2 1 q1 21
// if you read a 2 and then 0 or 1, go back to the
// initial state and keep reading input. otherwise,
// if you find a second two, proceed
q1 0 2 q0 02
q1 1 2 q0 12
q1 2 2 q2 22
// assume the '22' we just saw was not the one in
// the middle of the input string and that we need
// to keep reading input.
q2 0 2 q0 02
q2 1 2 q0 12
q2 2 2 q2 22
// assume the '22' we just saw was the one in the
// middle of the input string and that we now need
// to start reading from the stack.
q2 - 2 q3 -
q3 - 2 q4 -
q4 0 0 q4 -
q4 1 1 q4 -
q4 2 2 q4 -
q4 - Z q5 Z
// we read a string in the language and are
// ready to accept in q5. go to dead state q6
// explicitly if still have input.
q5 0 Z q6 Z
q5 1 Z q6 Z
q5 2 Z q6 Z
// consume the rest of the input in the dead state.
q6 0 Z q6 Z
q6 1 Z q6 Z
q6 2 Z q6 Z
The transitions for q5
and q6
aren't strictly necessary if you define crashing the machine to mean the string is definitively rejected, which is typical. I include those transitions so the PDA will gracefully exhaust all input without crashing.
This PDA is not deterministic. There is no deterministic PDA for this language. Basically, after we read any substring 22
, we have to guess whether that instance of 22
was the one in the middle. If so, we need to start reading the initial string back to see if we have a palindrome. If not, we need to keep pushing symbols on the stack.