Proofs: Greibach normal form conversion
These are the human proofs of Greibach normal form conversion, at full length.
The classical conversion gives an equivalent grammar in Greibach normal form full
This proof shows: correctness.
We use the pseudocode of the page and the notation of the grammar pages: productions , for the empty string, the start symbol. The input is . A production is in form if it is with , and all nonterminals. For a grammar and a nonterminal of write .
Theorem. The algorithm ends and returns a grammar with in which every production is in form, except when , and then is on no right side.
The proof has three parts: the steps that keep the language, the shape of the productions, and the end of the loops.
Part 1: the steps keep the language
Line L2. Let be the grammar after line L2. The three removals are the standard ones, done in the order -productions, unit productions, useless symbols.
- -productions. Let be the set of nullable nonterminals. Replace each production by all productions where comes from by deleting some of the that are in . Each new production is simulated by the old production and derivations for the deleted , so no new nonempty string is derived. Conversely, take a parse tree of a nonempty from in the old grammar. Delete every subtree whose frontier is empty; its root is nullable. A node keeps at least one child, because its frontier is nonempty. The node with some children deleted is a new production with . So is the same up to for every , and the new grammar has no -production.
- Unit productions. For each , let be the set of with by unit productions only. Replace all productions by for and a non-unit production. A new production is simulated by a chain of unit steps and one old production. Conversely, in a parse tree, each maximal chain of nodes joined by unit productions ends at a node with a non-unit production; contract the chain into one node. So the languages do not change, and no unit production remains. No -production appears, because only non-unit productions are copied.
- Useless symbols. First delete the nonterminals that derive no terminal string, and every production that contains one. Then delete the nonterminals not reachable from . A parse tree of a terminal string uses only symbols that derive terminal strings and that are reachable from its root, so does not change. If derives no terminal string, and is empty.
So . In every right side is nonempty, a right side of length 1 is a terminal, and every nonterminal derives some terminal string.
Line L4. Replacing a terminal in a non-first position by and adding keeps every , because derives exactly .
Substitution (lines L7, L9 and L10). Let be a production with a nonterminal different from , and let be all productions of . Replacing by keeps for every nonterminal . Each new production is simulated by two old ones. Conversely, in a tree of the old grammar, a node that uses has a first child that uses some ; merge the two nodes into one node that uses . Repeat until no node uses ; each merge removes one node, so this ends. The productions of do not change, because . Removing a duplicate production does not change the grammar as a set of productions.
Immediate left recursion (line L8). Let the productions of be , where no starts with , and let be a new nonterminal. The new productions are and . In the old grammar, a node of a parse tree starts a maximal chain of nodes along first children that use the productions , , …, and ends at a node that uses ; the chain derives . In the new grammar, (or when ), and every use of and in a new tree has this shape. So the two grammars derive the same sentential forms from by these blocks, and replacing each block by the other one maps trees to trees in both directions. Every for an old is kept. We need only to create , and holds because derives a terminal string, which a tree can only do by ending its chain at some .
Line L11. is computed on the input grammar, so is true if and only if . If is true, the new has the productions and for , so . If is false, the start symbol stays and .
So if the algorithm ends.
Part 2: the shape of the productions
Let the order after line L4 be , with the at the end. Call a production regular if it is a single terminal, or if it has length at least 2 and every symbol after the first is a nonterminal.
Claim 1. After line L4 every production is regular, and every later step keeps this.
After line L2 a right side of length 1 is a terminal, and line L4 makes every non-first symbol a nonterminal. A substitution replaces , with , by with regular and a nonempty string of nonterminals; the result has length at least 2, and its symbols after the first are those of after the first and those of , all nonterminals. In line L8, a production has length at least 2, so is a nonempty string of nonterminals, and so are . The productions are regular, and is regular because is nonempty.
So a regular production that starts with a terminal is in form. It remains to show that every production starts with a terminal at the end.
Claim 2. After iteration of the loop of line L5, every production of starts with a terminal or with some with , and the productions of do not change in later iterations.
By induction on . In iteration , the inner loop goes through . Before step , by the induction hypothesis for , no production of starts with for : such a production was replaced at step by productions that start with the first symbol of a production of , which is a terminal or an with ; if that production was in turn replaced at step , since the steps go in increasing order. After step no production starts with , by the same argument. So after the inner loop, every production of starts with a terminal or with , . Line L8 removes those with : the productions and start with the first symbol of , which is a terminal or with . Later iterations change only with and the new .
Claim 3. After line L9, every production of every starts with a terminal.
By Claim 2, the productions of start with terminals. Line L9 goes from down to 1. When it handles , the productions of all with already start with terminals, and every production of that starts with a nonterminal starts with such an , by Claim 2. Substituting gives productions that start with the first symbol of a production of , a terminal.
Claim 4. Every production of starts with some or with some with .
The productions of are and , where was a production when line L8 handled . By Claim 1, is a nonempty string of nonterminals, and the nonterminals that existed at that time were the and the created at an earlier iteration, so with . Lines L9 and L10 do not change which nonterminal starts a production of before line L10 handles .
Part 3: the loops end and finish the form
The loops of lines L5, L6 and L9 are bounded. Each substitution step is finite, because has finitely many productions.
For line L10, the implementation keeps the in a queue. It takes the first ; if a production of starts with a that is still in the queue, it puts back at the end, and otherwise it substitutes the leading nonterminal of each production of and removes from the queue.
Claim 5. The queue becomes empty, and then every production of every starts with a terminal.
While the queue is not empty, let be the element with the smallest index. By Claim 4 its productions start with an or with a with , and no such is in the queue. So within one pass through the queue, is handled and removed. The queue has at most elements, so it is empty after at most passes. When is handled, each production starts with an , whose productions start with terminals by Claim 3, or with a that has left the queue, whose productions start with terminals by induction on the order of removal. One substitution therefore makes every production of start with a terminal, and does not change afterwards.
By Claims 1, 3 and 5 every production of (including the ) and of every is regular and starts with a terminal, so it is in form. Line L11 adds and copies of the productions of , which are in form; is a fresh name and occurs on no right side. With Part 1, this proves the theorem.