compound_stmt: if_stmt | while_stmt | function_def | ...
if_stmt:
| 'if' named_expression ':' block elif_stmt
| 'if' named_expression ':' block [else_block]
elif_stmt:
| 'elif' named_expression ':' block elif_stmt
| 'elif' named_expression ':' block [else_block]
else_block:
| 'else' ':' block
block:
| NEWLINE INDENT statements DEDENT
| simple_stmts
...
\[\begin{align*} A &\to 0 A 11 \\ A &\to B \\ B &\to\ ! \end{align*}\]
Which of the following strings are generated by this grammar?
The set of strings generated is \(\{0^n ! 1^{2n} \mid n \geq 0\}\).
Let’s consider another CFG \(G\): \[\begin{align*} S &\to A B \\ A &\to 0 A \\ A &\to \emptystring \\ B &\to 1 B \\ B &\to \emptystring \end{align*}\]
We express this more concisely as: \[\begin{align*} S &\to A B \\ A &\to 0 A \or \emptystring \\ B &\to 1 B \or \emptystring \end{align*}\] where the \(\or\) symbol should be read as “or”.
Which of the following are generated by \(G\)?
The set of strings generated is matched by the regex \(0^* 1^*\).
Let’s consider another CFG \(G\): \[\begin{align*} S &\to A B \\ A &\to 0 A \\ A &\to \emptystring \\ B &\to 1 B \\ B &\to \emptystring \end{align*}\]
We express this more concisely as: \[\begin{align*} S &\to A B \\ A &\to 0 A \or \emptystring \\ B &\to 1 B \or \emptystring \end{align*}\] where the \(\or\) symbol should be read as “or”.
Parse tree for string 00111
Let’s generate all strings of properly nested parentheses.
For example, \(()\) and \((())()\) are valid, but \((()\) and \()(\) are not.
Parse tree for string \((()(()))\)
A context-free grammar (CFG) is a 4-tuple \(G = (\Gamma, \Sigma, S, \rho)\) where:
First some terminology:
A grammar \(G\) with start variable \(S\) accepts or generates/produces \(w \in \Sigma^*\) if \(S \derives w\).
The language of grammar \(G\) is \(L(G) = \setbuild{w \in \Sigma^*}{S \derives w}\).
A language \(A\) is called context-free or CFG-decidable if there exists a CFG \(G\) s.t. \(L(G) = A\).
Any DFA can trivially be converted into a CFG!
Consider the DFA \(M = (Q, \Sigma, \delta, s, F)\)
The resulting CFG decides (generates) exactly the same language as the DFA decides.
This is an example of a right-regular grammar (RRG):
A right-regular grammar (RRG) is a CFG where each rule is of the form: \(X \to a Y\) or of the form \(X \to \emptystring\).
Our third “declarative model of computation” is the Nondeterministic Finite Automaton.
What’s different here vs. our previous state diagrams?
Example processing the string \(010110\):
← Accept!