4.6.8 · Coding › Theory of Computation
Ek grammar ek recipe hai strings banane ki. Tum ek single symbol se start karte ho aur use rewrite karte rehte ho rules se, jab tak sirf "real" characters nahi reh jaate. CFGs woh recipes hain jo nested/recursive structure describe karne ke liye kaafi powerful hain — matched brackets, parentheses wala arithmetic, programming languages ka syntax — jo finite automata aur regular expressions nahi pakad sakte.
Context-free ka matlab hai: ek rule kisi symbol par apply ho sakta hai chahe uske aas-paas kuch bhi ho . Neighbours (context) kabhi rewrite ko block nahi karte.
Definition Context-free grammar
Ek CFG ek 4-tuple G = ( V , Σ , R , S ) hai jahan
V = variables ka finite set (non-terminals) — "placeholders jo abhi expand hone hain".
Σ = terminals ka finite set — final string ka actual alphabet (V ∩ Σ = ∅ ).
R = productions ka finite set, har ek ka form A → α hai jahan A ∈ V aur α ∈ ( V ∪ Σ ) ∗ .
S ∈ V = start symbol .
Sabse zaroori constraint left-hand side hai: ek context-free production mein woh exactly ek variable hota hai. (Agar LHS symbols ki ek string ho sakti, toh woh ek context-sensitive grammar hoti.)
Ek hi LHS wale kai rules | se stack kiye jaate hain:
A → α 1 ∣ α 2 ∣ α 3 means A → α 1 , A → α 2 , A → α 3 .
Empty string ε likhi jaati hai; ek rule A → ε A ko erase kar deta hai.
Grammar G 1 : S → ( S ) S ∣ ε .
(()) derive karo
S 1 ⇒ ( S ) S 2 ⇒ ( S ) 3 ⇒ (( S ) S ) 4 ⇒ (( S )) 5 ⇒ (( ))
Step 1 — kyun? Humein ek opening paren chahiye, toh S → ( S ) S use karo.
Step 2 — kyun? Outer string sirf ek balanced group honi chahiye, toh trailing S ko S → ε se khatam karo.
Step 3 — kyun? Andar ek aur nested pair chahiye → inner S ko phir S → ( S ) S se expand karo.
Steps 4–5 — kyun? Dono bache hue S 's kuch contribute nahi karte, toh S → ε do baar apply karo.
Result (()) ∈ L ( G 1 ) . Yeh grammar ek DFA se nahi ho sakti — unbounded nesting count karne ke liye ek stack chahiye, jo exactly wahi hai jo CFGs dete hain.
Ek derivation steps ki ek linear list hai, aur tum order ko kai tariikon se interleave kar sakte ho. Ek parse tree woh incidental ordering chhod deta hai aur sirf structural sach rakhta hai: kaun kiski child hai.
Definition Parse (derivation) tree
Root = start symbol S .
Har internal node ek variable A hai; agar usne rule A → X 1 X 2 … X k use kiya, toh uske children X 1 , … , X k hain left to right .
Ek node A → ε ka ek single ε leaf hota hai.
Yield = leaves ko left-to-right padhna = derived string.
G ambiguous hai agar kisi w ∈ L ( G ) ke do ya zyada distinct parse trees hain (equivalently, do distinct leftmost derivations). Ambiguity grammar ki property hai, language ki nahi.
Ambiguous grammar G 2 : E → E + E ∣ E ∗ E ∣ ( E ) ∣ a .
a + a * a ke liye do trees
Tree A (pehle multiply): E ⇒ E + E ⇒ a + E ⇒ a + E ∗ E ⇒ a + a ∗ E ⇒ a + a ∗ a . Yahan * tighter bind karta hai — value a + ( a ∗ a ) .
Tree B (pehle add): E ⇒ E ∗ E ⇒ E + E ∗ E ⇒ ⋯ ⇒ ( a + a ) ∗ a .
Do kyun? Grammar kabhi nahi batati + vs * ki precedence , toh dono groupings legal hain. Woh ambiguity hai, aur compilers ke liye buri hai kyunki meaning alag hoti hai.
Worked example Isse precedence layers se fix karo
Unambiguous G 3 :
E → E + T ∣ T , T → T ∗ F ∣ F , F → ( E ) ∣ a .
Teen levels kyun? Har layer = ek precedence tier. F (factor) sabse tight hai, phir T (term, *), phir E (expression, +). Ek + sirf top par baaith sakta hai, * ko pehle group hone par majboor karta hai. Recursion side (E → E + T , left-recursive) left-associativity fix karta hai. Ab a+a*a ka ek unique tree hai.
20% jo tumhare paas hona chahiye: (1) CFG = single-variable-LHS rewrite rules; (2) language = S se derivable saari terminal strings; (3) parse tree structure encode karta hai; (4) ambiguity = ≥2 parse trees. Inse tum har parser, har programming-language syntax, aur har woh nesting/counting problem ke baare mein reason kar sakte ho jisme regular expressions fail hote hain.
Common mistake "Lambi derivation ka matlab alag parse tree hai."
Kyun sahi lagta hai: zyada steps dikhte hain zyada structure jaisa. Fix: rewrites ki ordering irrelevant hai; sirf parent–child structure count karta hai. Compare karne se pehle derivation ko hamesha uske tree tak reduce karo — leftmost ↔ tree ek bijection hai, toh distinct derivations nahi, distinct trees gino.
Common mistake "Ek string ke do derivations grammar ki ambiguity prove karte hain."
Kyun sahi lagta hai: "do tarike" ambiguity jaisa lagta hai. Fix: tumhein do leftmost (ya do tree -distinct) derivations chahiye. Do derivations jo sirf variables expand karne ke order mein alag hain woh ek hi tree hain — ambiguity nahi.
Common mistake "Context-free ka matlab rules symbols ke order ko ignore karte hain."
Kyun sahi lagta hai: naam misleading hai. Fix: output mein order poori tarah matter karta hai (yeh ek string hai!). "Context-free" ka sirf matlab hai ki har rule ki left side ek single variable hai, toh applicability kabhi neighbours par depend nahi karti.
Common mistake Left-hand side par terminal rakhna, e.g.
a A → b .
Kyun sahi lagta hai: yeh ek normal pattern match jaisa lagta hai. Fix: woh context-sensitive hai, CFG nahi . CFG LHS = exactly ek variable, period.
Recall Ek CFG ke char components kya hain, aur LHS restriction kya hai?
G = ( V , Σ , R , S ) : variables, terminals, productions, start symbol. Har production ka LHS exactly ek variable hai ⇒ context-free.
Recall
L ( G ) precisely define karo.
L ( G ) = { w ∈ Σ ∗ ∣ S ⇒ ∗ w } — sirf fully-terminal strings jo S se derivable hain.
Recall Grammar ko ambiguous kya banata hai? (careful wording)
Kisi string ke do distinct parse trees hain (equiv. do distinct leftmost derivations). Grammar ki property hai, language ki nahi.
Recall DFA
{ ( n ) n } kyun recognize nahi kar sakta lekin CFG kar sakta hai?
Unbounded nesting ke liye unbounded counting chahiye (ek stack); finite states nahi kar sakte, lekin S → ( S ) ∣ ε freely recurse karta hai.
Recall Feynman: ek 12-saal ke bache ko parse tree explain karo.
Neeche hidden block dekho.
Recall (hidden Feynman)
Recall Explain like I'm 12
Grammar ko LEGO instructions samjho. Tum ek special block S se shuru karte ho. Har instruction kehta hai "tum is block ko in chote blocks se swap kar sakte ho." Tum tab tak swap karte rehte ho jab tak har block ek real letter na ho jo aur toot na sake — letters ki woh finished line tumhara word hai. Ek parse tree bas woh family photo hai jo dikhata hai kaun sa bada block kis chote block mein split hua. Agar wahi word do alag family photos mein build ho sakta hai, toh instructions sloppy the — woh sloppiness ambiguity kehlati hai.
"V Σ R S" ko "Very Smart Recipes Start" yaad rakho — Variables, Symbols(terminals Σ), Rules, Start . Aur "context-free" ke liye: "One on the Left" (LHS par ek variable).
Regular expressions and DFAs — strictly weaker ; CFGs ek stack ki memory add karte hain.
Pushdown automata — woh machine model jo exactly context-free languages accept karta hai.
Chomsky hierarchy — CFG = Type-2, regular (Type-3) aur context-sensitive (Type-1) ke beech.
Chomsky normal form — ek restricted CFG shape jo CYK parsing algorithm use karta hai.
Pumping lemma for CFLs — prove karta hai ki kuch languages context-free nahi hain.
Compilers — parsing — real-world use: source code ko parse/syntax trees mein convert karna.
Ek CFG formally kis 4-tuple ka hota hai? ( V , Σ , R , S ) — variables, terminals, productions, start symbol.
Productions par "context-free" kaunsi restriction define karti hai? Left-hand side exactly ek variable hota hai.
Ek production ka general form kya hai? A → α jahan A ∈ V aur α ∈ ( V ∪ Σ ) ∗ .
Ek derivation step ⇒ define karo. α A β ⇒ α γ β agar A → γ ∈ R ho; surrounding α , β unchanged.
L ( G ) kya hai?{ w ∈ Σ ∗ ∣ S ⇒ ∗ w } — saari terminal strings jo S se derivable hain.
Sentential form kya hota hai? S se derivable koi bhi string over V ∪ Σ (abhi bhi variables contain kar sakti hai).
Parse tree ka yield kya hai? Leaves ko left-to-right padhna = derived terminal string.
Leftmost vs rightmost derivation? Hamesha sabse leftmost (resp. rightmost) variable ko aage rewrite karo.
Ek parse tree se kitne leftmost derivations correspond karte hain? Exactly ek (bijection).
Ambiguous grammar ki definition? Kisi string ke ≥2 distinct parse trees hain (≥2 leftmost derivations).
Kya ambiguity language ki property hai ya grammar ki? Grammar ki; kuch languages ka ek unambiguous grammar hota hai.
Matched parentheses ke liye ek CFG do. S → ( S ) S ∣ ε .
{ a n b n } context-free kyun hai lekin regular nahi?Unbounded counting chahiye (ek stack); S → a S b ∣ ε karta hai, ek DFA nahi kar sakta.
E → E + E ∣ E ∗ E ∣ ( E ) ∣ a se ambiguity kaise hatate hain?Precedence layers use karo: E → E + T ∣ T , T → T ∗ F ∣ F , F → ( E ) ∣ a .
Exactly CFLs ko kaunsa automaton recognize karta hai? Pushdown automata (PDA).
CFG 4-tuple G V Sigma R S
Derivation step alpha A beta
Nested recursive structure