The definition of context free grammars (CFGs) allows us to develop a wide variety of grammars. Most of the time, some of the productions of CFGs are not useful and are redundant. This happens because the definition of CFGs does not restrict us from making these redundant productions.
By simplifying CFGs we remove all these redundant productions from a grammar , while keeping the transformed grammar equivalent to the original grammar. Two grammars are called equivalent if they produce the same language. Simplifying CFGs is necessary to later convert them into Normal forms.
Types of redundant productions and the procedure of removing them are mentioned below.
1. Useless productions – The productions that can never take part in derivation of any string , are called useless productions. Similarly , a variable that can never take part in derivation of any string is called a useless variable. For eg.
S -> abS | abA | abB A -> cd B -> aB C -> dc
In the example above , production ‘C -> dc’ is useless because the variable ‘C’ will never occur in derivation of any string. The other productions are written in such a way that variable ‘C’ can never reached from the starting variable ‘S’.
Production ‘B ->aB’ is also useless because there is no way it will ever terminate . If it never terminates , then it can never produce a string. Hence the production can never take part in any derivation.
To remove useless productions , we first find all the variables which will never lead to a terminal string such as variable ‘B’. We then remove all the productions in which variable ‘B’ occurs.
So the modified grammar becomes –
S -> abS | abA A -> cd C -> dc
We then try to identify all the variables that can never be reached from the starting variable such as variable ‘C’. We then remove all the productions in which variable ‘C’ occurs.
The grammar below is now free of useless productions –
S -> abS | abA A -> cd
2. λ productions – The productions of type ‘A -> λ’ are called λ productions ( also called lambda productions and null productions) . These productions can only be removed from those grammars that do not generate λ (an empty string). It is possible for a grammar to contain null productions and yet not produce an empty string.
To remove null productions , we first have to find all the nullable variables. A variable ‘A’ is called nullable if λ can be derived from ‘A’. For all the productions of type ‘A -> λ’ , ‘A’ is a nullable variable. For all the productions of type ‘B -> A1A2…An ‘ , where all ’Ai’s are nullable variables , ‘B’ is also a nullable variable.
After finding all the nullable variables, we can now start to construct the null production free grammar. For all the productions in the original grammar , we add the original production as well as all the combinations of the production that can be formed by replacing the nullable variables in the production by λ. If all the variables on the RHS of the production are nullable , then we do not add ‘A -> λ’ to the new grammar. An example will make the point clear. Consider the grammar –
S -> ABCd (1) A -> BC (2) B -> bB | λ (3) C -> cC | λ (4)
Lets first find all the nullable variables. Variables ‘B’ and ‘C’ are clearly nullable because they contain ‘λ’ on the RHS of their production. Variable ‘A’ is also nullable because in (2) , both variables on the RHS are also nullable. Similarly , variable ‘S’ is also nullable. So variables ‘S’ , ‘A’ , ‘B’ and ‘C’ are nullable variables.
Lets create the new grammar. We start with the first production. Add the first production as it is. Then we create all the possible combinations that can can be formed by replacing the nullable variables with λ. Therefore line (1) now becomes ‘S -> ABCd | ABd | ACd | BCd | Ad | Bd |Cd | d ’.We apply the same rule to line (2) but we do not add ‘A -> λ’ even though it is a possible combination. We remove all the productions of type ‘V -> λ’. The new grammar now becomes –
S -> ABCd | ABd | ACd | BCd | Ad | Bd |Cd | d A -> BC | B | C B -> bB | b C -> cC | c
3. Unit productions – The productions of type ‘A -> B’ are called unit productions.
To create a unit production free grammar ‘Guf’ from the original grammar ‘G’ , we follow the procedure mentioned below.
First add all the non-unit productions of ‘G’ in ‘Guf’. Then for each variable ‘A’ in grammar ‘G’ , find all the variables ‘B’ such that ‘A *=> B’. Now , for all variables like ‘A ’ and ‘B’, add ‘A -> x1 | x2 | …xn’ to ‘Guf’ where ‘B -> x1 | x2 | …xn ‘ is in ‘Guf’ . None of the x1 , x2 … xn are single variables because we only added non-unit productions in ‘Guf’. Hence the resultant grammar is unit production free. For eg.
S -> Aa | B A -> b | B B -> A | a
Lets add all the non-unit productions of ‘G’ in ‘Guf’. ‘Guf’ now becomes –
S -> Aa A -> b B -> a
Now we find all the variables that satisfy ‘X *=> Z’. These are ‘S *=> A’ , ‘S*=>B’, ‘A *=> B’ and ‘B *=> A’. For ‘A *=> B’ , we add ‘A -> a’ because ‘B ->a’ exists in ‘Guf’. ‘Guf’ now becomes
S -> Aa A -> b | a B -> a
For ‘B *=> A’ , we add ‘B -> b’ because ‘A -> b’ exists in ‘Guf’. The new grammar now becomes
S -> Aa A -> b | a B -> a | b
We follow the same step for ‘S *=> A’ and ‘S*=>B’ and finally get the following grammar –
S -> Aa | b | a A -> b | a B -> a | b
Note: To remove all kinds of productions mentioned above, first remove the null productions, then the unit productions and finally , remove the useless productions. Following this order is very important to get the correct result.
This article is contributed by Nitish Joshi. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
- Closure Properties of Context Free Languages
- Ambiguity in Context free Grammar and Context free Languages
- Ambiguity in Context free Grammar and Context free Languages
- Context-sensitive Grammar (CSG) and Language (CSL)
- Converting Context Free Grammar to Chomsky Normal Form
- Converting Context Free Grammar to Greibach Normal Form
- Check if the language is Context Free or Not
- Regular Expression Vs Context Free Grammar
- Closure properties of Regular languages
- Difference between Pushdown Automata and Finite Automata
- Determining Countability in TOC
- Removing Direct and Indirect Left Recursion in a Grammar
- Total Recursive Functions and Partial Recursive Functions in Automata
- Variation of Turing Machine