$\begin{array}{l} \textrm{There are NO rules in this grammar} \\ \end{array}$
The empty language, the language of no strings, is absolutely NOT the same as the language containing only the empty string.
While the best answer is that the grammar has a empty set of rules, it is also acceptable to create a one-rule grammar of the form $s \longrightarrow s$. In this grammar, you can never derive anything, so, it does work, but it’s not a great answer.
$\begin{array}{lcl} \textit{s} & \longrightarrow & \textit{x}\;\texttt{"2"}^* \mid \texttt{"0"}^* \;\textit{y} \\ \textit{x} & \longrightarrow & \varepsilon \mid \texttt{"0"}\;\textit{x}\;\texttt{"1"} \\ \textit{y} & \longrightarrow & \varepsilon \mid \texttt{"1"}\;\textit{y}\;\texttt{"2"} \\ \end{array}$
$\begin{array}{lcl} s & \longrightarrow & (\textit{x}\;\texttt{"1"})^*\;\textit{x} \\ x & \longrightarrow & ε \mid \texttt{"0"} \mid \texttt{"00"} \end{array}$
This generates an arbitrary number of “chunks” of at most two zeros separated by 1s
$\begin{array}{lcl} s & \longrightarrow & x^* \\ x & \longrightarrow & \texttt{"a"}\;\textit{x}\;\texttt {"a"}\;\textit{x}\;\texttt{"b"} \mid \texttt{"a"}\;\textit{x}\;\texttt{"b"}\;\textit{x}\;\texttt {"a"} \mid \texttt{"b"}\;\textit{x}\;\texttt{"a"}\;\textit{x}\;\texttt{"a"} \\ \end{array}$
This generates zero or more “chunks” each of which has twice as many $a$’s as $b$’s. There are three ways to form a chunk: (1) $\texttt{a---a---b}$, (2) $\texttt{a---b---a}$, and (3) $\texttt{b---a---a}$.
$\begin{array}{lcll} s & \longrightarrow & (\texttt{"a"}\;0\;\texttt{"b"}\;1\;\texttt{"a"}\;2\;\texttt{"b"})? & \textrm{Place marks between blocks} \\ \texttt{"a"}\;0 & \longrightarrow & \texttt{"aa"}\;0\;x & \textrm{New a's at the beginning} \\ x\;\texttt{"b"} & \longrightarrow & \texttt{"b"}\;x & \textrm{Move x's to the right of b's} \\ x\;1 & \longrightarrow & \texttt{"b"}\;1\;x & \textrm{When x hits the 1, make a new b} \\ x\;\texttt{"a"} & \longrightarrow & \texttt{"a"}\;x & \textrm{Move x past the second batch of a's} \\ x\;2 & \longrightarrow & \texttt{"a"}\;2\;\texttt{"b"} & \textrm{When x hits the 2, generate an ab on the right} \\ 0 & \longrightarrow & ε & \textrm{Drop the marks at any time} \\ 1 & \longrightarrow & ε & \\ 2 & \longrightarrow & ε & \\ \end{array}$
There is probably a much better way.
To show the grammar in the standard $(V, \Sigma, R, S)$ form we have to get rid of all the wonderful convenient operators and introduce new variables. Here I added $s$ to stand for “sequence of one or more digits.” Also, since $e$ appears in the language but was also being used as a variable, I’ve changed the $e$ variable to $x$ (still stands for “exponent part”).
$\begin{array}{l} (\\ \;\;\;\; \{ n, s, f, x, d \}, \\ \;\;\;\; \{ 0,1,2,3,4,5,6,7,8,9,.,E,e,+,- \}, \\ \;\;\;\; \{ \\ \;\;\;\;\;\;\;\; (n, sfx), \\ \;\;\;\;\;\;\;\; (s, d), (s, ds), \\ \;\;\;\;\;\;\;\; (f,ε), (f,.s), \\ \;\;\;\;\;\;\;\; (x,ε), (x,Es), (xE+s), (x,E-s), (x,es), (x,e+s), (x,e-s), \\ \;\;\;\;\;\;\;\; (d,0), (d,1), (d,2), (d,3), (d,4), (d,5), (d,6), (d,7), (d,8), (d,9) \\ \;\;\;\; \}, \\ \;\;\;\; n \\ ) \\ \end{array}$
Turing Machine recognizers:
State | Symbol | Actions | Next |
---|---|---|---|
GoingToEnd | $a$ | Right | GoingToEnd |
GoingToEnd | $b$ | Right | GoingToEnd |
GoingToEnd | $\#$ | Left | AtLast |
AtLast | $b$ | Left | AtSecondToLast |
AtSecondToLast | $b$ | Left | AtThirdToLast |
AtThirdToLast | $a$ | — | Accept |
State | Symbol | Actions | Next |
---|---|---|---|
Accept | $X$ | Right | Accept |
Accept | $a$ | Print $X$, Right | LookingForFirstB |
Accept | $b$ | Print $X$, Right | LookingForFirstA |
LookingForFirstA | $X$ | Right | LookingForFirstA |
LookingForFirstA | $b$ | Right | LookingForFirstA |
LookingForFirstA | $a$ | Print $X$, Left | ReturningToStart |
LookingForFirstB | $X$ | Right | LookingForFirstB |
LookingForFirstB | $a$ | Right | LookingForFirstB |
LookingForFirstB | $b$ | Print $X$, Left | ReturningToStart |
ReturningToStart | $X$ | Left | ReturningToStart |
ReturningToStart | $a$ | Left | ReturningToStart |
ReturningToStart | $b$ | Left | ReturningToStart |
ReturningToStart | $\#$ | Right | Accept |
State | Symbol | Actions | Next |
---|---|---|---|
Accept | $a$ | Right | NeedB |
Accept | $b$ | Right | NeedA |
NeedA | $a$ | Right | Accept |
NeedB | $b$ | Right | Accept |
Turing Machine transducers:
State | Symbol | Actions | Next |
---|---|---|---|
GoingToEnd | $0$ | Right | GoingToEnd |
GoingToEnd | $1$ | Right | GoingToEnd |
GoingToEnd | $\#$ | Left | Flipping1sToIncrement |
Flipping1sToIncrement | $1$ | Print $0$, Left | Flipping1sToIncrement |
Flipping1sToIncrement | $0$ | Print $1$, Right | Incremented |
Flipping1sToIncrement | $\#$ | Print $1$, Right | Incremented |
Incremented | $\#$ | Print $0$ | IncrementedAndDoubled |
State | Symbol | Actions | Next |
---|---|---|---|
Flipping | $0$ | Print $1$, Right | Flipping |
Flipping | $1$ | Print $0$, Right | Flipping |
lambda n: str(n)[1:-1]
. This is done by ”erasing” the first and last symbols, i.e., writing over them with blanks.
State | Symbol | Actions | Next |
---|---|---|---|
Start | $0$ | Print $\#$, Right | FirstSymbolErased |
Start | $1$ | Print $\#$, Right | FirstSymbolErased |
FirstSymbolErased | $0$ | Right | FirstSymbolErased |
FirstSymbolErased | $1$ | Right | FirstSymbolErased |
FirstSymbolErased | $\#$ | Left | AtLastSymbol |
AtLastSymbol | $0$ | Print $\#$ | FirstAndLastSymbolErased |
AtLastSymbol | $1$ | Print $\#$ | FirstAndLastSymbolErased |
The expression 5 * 3 - 1 ** 3 can be evaluated on a 3AC machine like this:
MUL 5, 3, r1 POW 1, 3, r2 SUB r1, r2, r0
and on a 0AC (stack) machine like this:
PUSH 5 PUSH 3 MUL PUSH 1 PUSH 3 POW SUB
Note that LOAD and PUSH are equivalent instructions.