Context-Free Grammars
COS2601 - Theoretical Computer Science II · Pushdown Automata Theory
Context-Free Grammars
Syntax is a method for defining languages. Early computer input devices required a way to write complicated algebraic expressions in a linear format. This led to the need for a formal system to represent these expressions. A formal language consists of rules that govern how symbols can be combined to create valid strings. This is where context-free grammars (CFGs) come into play.
Definition of Context-Free Grammar
A context-free grammar (CFG) is defined by three components:
- An alphabet of letters called terminals, which are the symbols used to create strings in the language.
- A set of symbols called nonterminals, which include a special symbol, usually denoted as S, representing the start of the grammar.
- A finite set of productions, which are rules that describe how nonterminals can be replaced with strings of terminals and/or nonterminals.
Productions have the form:
Nonterminal → string of terminals and/or nonterminals
At least one production must have S as its left side. Nonterminals are typically represented by capital letters, while terminals are in lowercase or special symbols.
Generating Strings with CFGs
The language generated by a CFG is the set of all strings of terminals that can be produced from the start symbol S using the productions. For example, consider the following CFG:
PROD 1: S → aS
PROD 2: S → AHere, if we apply production 1 six times and then production 2, we can generate the string a6:
S → aS
→ aaS
→ aaaS
→ aaaaS
→ aaaaaS
→ aaaaaaS
→ aaaaaaA
→ aaaaaaThis derivation shows that the CFG generates the language a*, which consists of any number of a's, including the empty string.
Derivations and Productions
The process of generating a string from a CFG involves applying productions to replace nonterminals with terminals or other nonterminals. The sequence of these applications is called a derivation. For example, consider another CFG:
PROD 1: S → SS
PROD 2: S → a
PROD 3: S → ATo derive the string aa using this CFG, we can proceed as follows:
S → SS → aS → aaIn this case, the language generated is still a*, but different productions lead to the same result.
Understanding Terminals and Nonterminals
In CFGs, terminals are the symbols that appear in the final strings of the language, while nonterminals are placeholders that can be replaced by groups of terminals or other nonterminals. For example, in the production:
S → aSbThe nonterminal S can be replaced recursively, allowing for the generation of strings like anbn where n is a non-negative integer.
Example of a CFG
Let us define a CFG with terminals a and b, and nonterminal S:
PROD 1: S → aSb
PROD 2: S → A
PROD 3: S → bThis CFG generates strings with balanced a's and b's. For instance:
S → aSb → aaSbb → aabThe language generated by this CFG is { anbn | n ≥ 0 }.
Parsing and Validating Strings
Parsing is the process of determining how a string can be formed from the rules of a grammar. A parser reads an input string and applies the productions of the CFG to validate whether the string belongs to the language defined by the CFG.
For example, if we have the string aab, we can parse it as follows:
S → aSb → aaSbb → aabThis shows that aab is a valid string in the language.
Common Errors in CFGs
Watch out: A common mistake is to confuse terminals and nonterminals. Always remember that terminals are the final symbols in generated strings, while nonterminals are placeholders.
Examples of Context-Free Languages
Context-free languages (CFLs) are languages that can be generated by CFGs. Here are some examples:
- The language of balanced parentheses: { ( ) | n ≥ 0 }
- The language of palindromes: { w | w = wR, w ∈ {a, b}* }
- The language of strings with equal numbers of a's and b's: { anbn | n ≥ 0 }
Conclusion
Context-free grammars provide a powerful way to define and generate languages. They consist of terminals, nonterminals, and production rules that allow for the recursive generation of strings. Understanding CFGs is essential for working with programming languages and compilers.
Check your understanding
- What are the three components of a context-free grammar?
- Explain the difference between terminals and nonterminals in a CFG.
- How would you derive the string aab using a specific CFG?
- What is the significance of the start symbol S in a CFG?