300 likes | 501 Views
Simplifying CFL’s. Reading: 6.1. Grammar Simplification. We want to change the production rule styles of CFL’s to prove properties. Simplification: removing undesirable types of production rules without changing the language that the grammar defines.
E N D
Simplifying CFL’s Reading: 6.1
Grammar Simplification • We want to change the production rule styles of CFL’s to prove properties. • Simplification: removing undesirable types of production rules without changing the language that the grammar defines. • Simplification does not always result in fewer rules!
Removing Lambda • We want lambda-free grammars, so that we don’t deal with special empty cases. • We can write lambda-free grammars for any language that does not contain the string lambda. • Otherwise, consider the language L – {λ}
Removing Production Rules • If you want to remove a rule of a CFL that has only one variable on the right, • Exchange the rule with a set of rules that inserts all one-step derivations of the variable on the right. A -> a | aaA | abBc B -> abbA | b A -> a | aaA | ababbAc | abbc
Nullable Variables • Nullable Variables are those that can be replaced with lambda. • We often want to remove lambda production rules • Doing so makes a grammar with no nullable variables
Algorithm for removing lambda and Nullable Variables • For any production rule in the grammar of the form A -> λ • Replace all right-hand occurrences of A with an option that has A replaced with λ.
Example: Removing lambda S -> aAb A -> aAb | λ Becomes: S -> aAb | ab A -> aAb | ab
Example: Removing Lambda Iteration 1: (B) S -> ABaC | AaC A -> BC | C B -> b C -> D | λ D -> d Iteration 2: (C) S -> ABaC | AaC | ABa | Aa A -> BC | C | B | λ B -> b C -> D D -> d S -> ABaC A -> BC B -> b | λ C -> D | λ D -> d Iteration 3: (A) S -> ABaC | AaC | ABa | Aa | BaC | aC | Ba | a A -> BC | C | B B -> b C -> D D -> d
Useful Variables • A variable in a grammar is said to be useful if there is at least one string w in the language such that S * xAy * w where x & y are any sequences of variables and terminals. • A variable is useful if it is used in the derivation of at least one string. • Otherwise, it is useless.
Finding Useless Variables • A variable may be useless if there is no way to get a terminal string from it: S -> aSb | a | A A -> aA A is useless in this example, because it can never lead to terminals.
Finding Useless Variables • A variable might be useless if there is no way to reach it from the start symbol. S -> A A -> aA | a B -> bA B is useless – there is no other production rule that uses it.
Dependency Graph • A way to tell if a variable is useless because it is unreachable from S. • Make a node for every variable. • Place arcs from node A to node B if B appears on the right of a production of A. • A useless variable is any that cannot be reached in the graph from S.
Dependency Graph Example S -> aaA | ab A -> bC B -> Cab C - > a | bb B is useless because it is unreachable from S. A S C B
Algorithm for Removing All Useless Variables (Part 1) • Make a set V1, initialize to { } • Loop: • Look at each variable V in turn • Look at each of V’s production rules • If everything on the right of the production rule is either a terminal or a variable in V1, add V to V1 • Continue Loop until the iteration adds no variables to V1. • Keep all production rules whose variables are all in V1.
Algorithm for Removing All Useless Variables (Part 2) • Part 1 kept all variables that result in terminal strings. • Part 2 will keep all variables reachable from the start symbol. • Draw the dependency graph for the new grammar. • Keep only the production rules in which all variables can be reached in the dependency graph.
Example • Remove all useless symbols and productions from the following grammar: S -> aS | A | C A -> a B -> aa C -> aCb
Step 1 Start with V1 = { } Iteration 1: V1 = {A,B} Iteration 2: V1 = {A,B,S} Iteration 3: V1 = {A,B,S} S -> aS | A | C A -> a B -> aa C -> aCb
Step 2 S -> aS | A A -> a B -> aa A S B Final Grammar: S -> aS | A A -> a
Unit Productions • Any production where one variable is replaced with another is a unit production. • Any rule of the form A -> B • Unit production rules are sometimes undesirable. (Exhaustive Search Parsing) • A -> A can be removed with no effect.
Removing Unit Production Rules • Part one: Draw a unit-rule dependency graph. That is, a dependency graph based only on unit production rules. • Find pairs A-> B such that there is a walk in the graph from A to B. • Part two: For each pair A -> B, add an option which substitutes non-unit resolutions of B to the right hand side of A.
Removing Unit Productions Example S -> Aa | B B -> A | bb A -> a | bc | B S A B Pairs are: S-> BS -> AA -> BB -> A
Removing Unit Rules Original: S -> Aa | B Minus Units: S-> Aa B -> A | bb B -> bb A -> a | bc | B A -> a | bcFor each pair, add substitutions from the “Minus” Grammar: (S -> A) S -> Aa | a | bc (S -> B) S -> Aa | a | bc | bb (B -> A)B -> bb | a | bc (A -> B)A -> a | bc | bb
Removing Units Final Grammar is : S -> Aa | a | bc | bb B -> bb | a | bc A -> a | bc | bb
Complete Simplification: • Remove lambda productions • Remove unit productions • Remove useless productions