Table of Contents
- Context Free Grammars (CFG)
- Regular Languages are Context-free
- Parse Trees
- Pushdown Automata
- Algorithmic Properties
1. Context Free Grammars (CFG)
Definition
A context-free grammar is a quadruple where:
- is an alphabet (set of all symbols)
- (the set of terminals) is a subset of
- Terminal symbols are the actual characters in the language (e.g., )
- (the set of rules) is a finite subset of
- Rules define how non-terminals can be replaced
- (the start symbol) is an element of
- This is where all derivations begin
Key Components:
- Non-terminals: Elements of (phrase types, variables)
- These are symbols that can be further expanded
- Terminals: Elements of (actual symbols in strings)
Analogy: Think of a CFG like a recipe. Non-terminals are instructions like "add filling," while terminals are actual ingredients like "sugar" and "flour." The start symbol is "make cake," and rules tell you how to break down each instruction into smaller steps or actual ingredients.
Grammar Rules and Derivations
Notation:
- We write for any rule
- This means: "A generates u" or "A can be replaced by u"
Derivation:
- For any strings , we write if and only if:
- There is a rule in
- (string with somewhere in it)
- (same string but replaced with )
This means you can derive from by replacing one non-terminal with its production rule.
Multi-step Derivation:
- A sequence where is called a derivation of from
- We write if there exists a derivation for from
- The asterisk * means "zero or more steps"
Language Generated by G:
- This is the set of all strings of terminal symbols that can be derived from the start symbol
Exam Tip: When showing derivations, work step-by-step and replace only ONE non-terminal at a time. Make sure your final result contains only terminal symbols.
Example: Grammar for Arithmetic Expressions
Consider grammar where:
Terminals:
Variables:
Start Symbol: (Expression)
Rules :
E → E + T (Expression can be Expression plus Term)
E → T (Expression can be just a Term)
T → T * F (Term can be Term times Factor)
T → F (Term can be just a Factor)
F → (E) (Factor can be parenthesized Expression)
F → x (Factor can be variable x)
Real-world use: This grammar structure is used in compilers to parse mathematical expressions in programming languages. The hierarchy (Expression → Term → Factor) enforces operator precedence: multiplication before addition.
Derivation Examples
Example 1: Derive
Example 2: Derive
Exam Strategy: Label which rule you're using at each step. This makes it easy for graders to follow your work and gives you partial credit even if you make a mistake later.
2. Regular Languages are Context-free
Theorem
Relationship: (Regular Languages are a subset of Context-Free Languages)
This means CFGs are more powerful than regular expressions and finite automata. They can describe all regular languages PLUS more complex languages.
Proof (Converting FSA to CFG)
Given:
- A regular language accepted by a deterministic finite automaton
Construct:
- A grammar as follows:
Construction:
- (variables are the states plus terminals)
- Start symbol = initial state of the DFA
- Rules consist of:
- where
- For each transition from state to state on symbol
- for
- For each accepting state
- where
Example Conversion:
FSA Transition: Grammar Rule:
[P] --a--> [Q] → P → aQ
[P] is accepting → P → ε
Intuition: Each state becomes a non-terminal. Each transition becomes a rule that "consumes" a symbol and moves to the next state. Accepting states have rules that allow the derivation to terminate.
Proof Sketch:
By induction, we can show:
if and only if
Therefore, for any string :
- ⟺ and
- ⟺ and in
- ⟺
Example CFGs for Non-Regular Languages
Example 1:
This language is NOT regular (it requires counting/memory), but it IS context-free.
Grammar:
S → ab
S → aSb
S → ε
Derivation for :
Real-world application: This pattern appears in matching opening and closing brackets in code:
(),((())), etc.
Example 2:
This language is NOT context-free (requires counting two independent counters simultaneously).
3. Parse Trees (Derivation Trees)
Definition
A parse tree (or derivation tree) is a graphical representation of a derivation.
Structure:
- Root: The start symbol or a non-terminal
- Internal nodes: Non-terminal symbols
- Leaves: Terminal symbols or
- Yield: The string formed by reading leaves from left to right
Construction Rules for Parse Trees
Let
Rule 1: Terminal Symbols
For each , the tree:
a
is a parse tree with:
- Root:
- Only leaf:
- Yield:
Rule 2: Epsilon Rules
If is a rule in , then:
A
|
ε
is a parse tree with:
- Root:
- Only leaf:
- Yield:
Rule 3: Multiple Children
If are parse trees (where ) with:
- Roots:
- Yields:
And is a rule in , then:
A
/|\
/ | \
A₁ A₂ Aₙ
| | |
T₁ T₂ Tₙ
is a parse tree with:
- Root:
- Leaves: All leaves of
- Yield:
Parse Tree Examples
Example 1: Parse tree for
E
|
T
|
F
/|\
( E )
|
T
|
F
|
x
Yield:
Example 2: Grammar for
Grammar:
S → ab
S → aSb
Parse tree for :
S
/|\
a S b
/|\
a S b
/|\
a S b
|
ε
Yield:
Exam Tip: Always verify your parse tree by reading the leaves from left to right - this should give you your target string.
Key Lemma
Theorem: Let be a context-free grammar, , and .
The following statements are logically equivalent:
- There exists a parse tree with root and yield
This means: Derivations and parse trees are two ways of representing the same thing. A derivation is the "process" and a parse tree is the "structure."
4. Left-most and Right-most Derivations
Left-most Derivation
Definition: We write if the non-terminal symbol being replaced is the leftmost non-terminal in the string.
- where , , and is a rule in
Form:
Example:
Right-most Derivation
Definition: We write if the non-terminal symbol being replaced is the rightmost non-terminal in the string.
- where , , and is a rule in
Form:
Example:
Key Insight: The ORDER of applying derivation rules doesn't matter for the final result, but it creates a different "path" through the derivation. Left-most and right-most are standard conventions used by parsers.
Equivalence Theorem
Theorem: Let be a context-free grammar, , and .
The following statements are equivalent:
- (some derivation exists)
- There is a parse tree with root and yield
- (left-most derivation exists)
- (right-most derivation exists)
Meaning: No matter which order you apply the rules (left-most, right-most, or random), you'll get the same parse tree and same final string. The derivation path differs, but the result is the same.
Exam Application: You can choose whichever derivation order is easiest for you! Left-most is often more intuitive.
5. Ambiguity
Ambiguous vs Unambiguous Grammars
Let . Consider two grammars for the same language:
Grammar G₁ (Unambiguous)
V₁ = Σ ∪ {T, F, E}
R₁ = {
E → E + T
E → T
T → T * F
T → F
F → (E)
F → x
}
Property: For each string , there is exactly one parse tree that yields .
Parse tree for :
E
/|\
E + T
| /|\
T T * F
| | |
F F x
| |
x x
This correctly shows that multiplication happens before addition.
Grammar G₂ (Ambiguous)
V₂ = Σ ∪ {E}
R₂ = {
E → E + E
E → E * E
E → (E)
E → x
}
Property: There are distinct parse trees yielding the same string.
Two different parse trees for :
Tree 1 (multiplication first):
E
/|\
E + E
| /|\
x E * E
| |
x x
Tree 2 (addition first):
E
/|\
E * E
/|\ |
E + E x
| |
x x
Problem: Ambiguity means the grammar doesn't uniquely determine how to parse an expression, leading to potential misinterpretation of meaning.
Definition of Ambiguity
A grammar is ambiguous if:
A grammar is unambiguous if:
Real-world Impact: Programming language compilers need unambiguous grammars. Otherwise, the same code could be interpreted different ways, leading to bugs and security vulnerabilities.
Spotting Ambiguity
How to identify ambiguous grammars:
- Look for recursive rules on both sides:
- (both left and right are the same non-terminal)
- This creates multiple ways to group operations
- Missing operator precedence rules:
- When all operators are at the same level in the grammar
- Example: treats and equally
- No associativity specification:
- doesn't specify left or right associativity
- Can parse as or
Common culprits:
E → E + E // Ambiguous (left or right associative?)
E → E * E // Ambiguous (same issue)
E → (E)
E → x
How to fix:
E → E + T // Unambiguous (forces left associativity for +)
E → T
T → T * F // Unambiguous (forces left associativity for *)
T → F
F → (E)
F → x
The hierarchy enforces precedence: binds tighter than .
Exam Tip: If asked "What makes this grammar ambiguous?", look for rules like where the same non-terminal appears on both sides of an operator.
Summary & Key Takeaways
Context-Free Grammars
- Definition:
- More powerful than regular expressions
- Can handle nested structures (balanced parentheses, etc.)
Key Relationships
- Regular Languages ⊂ Context-Free Languages ⊂ All Languages
- Any FSA can be converted to an equivalent CFG
- Not all CFLs are regular (e.g., )
Derivations & Parse Trees
- Derivation: Step-by-step application of rules
- Parse Tree: Graphical representation of structure
- Equivalence: Any derivation corresponds to exactly one parse tree (if unambiguous)
Left-most vs Right-most
- Different paths to the same result
- Useful for parser implementation
- Don't affect final yield or parse tree structure
Ambiguity
- Critical for compilers: Need unambiguous grammars
- Detection: Look for symmetric recursion ()
- Resolution: Introduce hierarchy and enforce precedence
Exam Tips Summary
- For derivations: Work step-by-step, label rules used
- For parse trees: Verify yield by reading leaves left-to-right
- For ambiguity questions: Look for recursive rules and lack of precedence
- For conversions: FSA → CFG is straightforward (states become non-terminals)
- Time management: Start with simpler derivations, come back to complex ones
Real-World Applications
Compilers & Programming Languages
- Parsing source code syntax
- Enforcing operator precedence
- Checking balanced brackets, parentheses
Natural Language Processing
- Parsing sentence structure
- Grammar checking
- Machine translation
Data Formats
- XML/HTML parsing
- JSON validation
- Configuration file parsing
Protocol Design
- Network protocol specification
- API definition languages
- Communication format standards
Additional Practice Problems
Problem 1
Design a CFG for
Problem 2
Prove that is NOT context-free (requires Pumping Lemma for CFLs)
Problem 3
Convert the following NFA to a CFG:
- States:
- Initial:
- Accepting:
- Transitions: ,
Problem 4
Show that the following grammar is ambiguous and provide an unambiguous equivalent:
S → aSb | SS | ε