CD Notes
Complete guide to regular expressions used in lexical analysis, including operations, properties, algebraic laws, and their use in token specification.
Introduction
Regular expressions (regex) are a fundamental notation for specifying patterns of strings. In compiler design, they serve as the primary mechanism for defining token patterns. Every token in a programming language can be described by a regular expression, and these expressions can be systematically converted into finite automata for efficient pattern matching.
Basic Operations
1. Concatenation
Two regular expressions joined together match strings that are concatenations of strings matched by each.
2. Alternation (Union)
The | operator matches strings matched by either operand.
3. Kleene Closure (Star)
The * operator matches zero or more repetitions.
4. Positive Closure
The + operator matches one or more repetitions.
5. Optional (Question Mark)
The ? operator matches zero or one occurrence.
Operator Precedence
From highest to lowest:
| Priority | Operator | Name | |
|---|---|---|---|
| 1 (highest) | * + ? | Closure operators | |
| 2 | concatenation | Concatenation | |
| 3 (lowest) | \ | Alternation |
Example
Extended Notation
Character Classes
| [abc] | a | b | c |
| [a-z] | a | b | c | ... | z |
| [A-Za-z] | any letter |
| [0-9] | any digit |
| [^abc] | any character except a, b, c |
Predefined Classes
| \d | [0-9] (digit) |
| \w | [A-Za-z0-9_] (word character) |
| \s | [ \t\n\r] (whitespace) |
| . | any character except newline |
Quantifiers
| r{n} | exactly n repetitions |
| r{n,} | n or more repetitions |
| r{n,m} | between n and m repetitions |
Regular Definitions
A regular definition gives names to regular expressions for readability:
| letter | [A-Za-z] |
| digit | [0-9] |
| id | letter (letter | digit)* |
| number | digit+ (. digit+)? (E [+-]? digit+)? |
Important: Regular definitions must not be recursive (no self-reference).
Token Patterns Using Regular Expressions
Complete Token Specification Example
Algebraic Laws of Regular Expressions
| Law | Expression | Equivalent | ||||
|---|---|---|---|---|---|---|
| Commutative | r \ | s | s \ | r | ||
| Associative | (r \ | s) \ | t | r \ | (s \ | t) |
| Associative | (rs)t | r(st) | ||||
| Identity | εr = rε | r | ||||
| Identity | r \ | ∅ | r | |||
| Annihilator | ∅r = r∅ | ∅ | ||||
| Distributive | r(s \ | t) | rs \ | rt | ||
| Distributive | (s \ | t)r | sr \ | tr | ||
| Idempotent | r \ | r | r | |||
| Closure | r* | (r \ | ε)* | |||
| Closure | r** | r* | ||||
| Closure | (r*)* | r* |
Converting Regular Expressions to Token Recognizers
The process of building a lexical analyzer:
| Example | (a|b)*abb |
| Step 1 | Build NFA (Thompson's construction) |
| Step 2 | Convert NFA to DFA (subset construction) |
| Step 3 | Minimize DFA (remove equivalent states) |
| Step 4 | Implement as transition table |
Practical Examples
Example 1: Email Pattern (Simplified)
Example 2: C Integer Constants
Example 3: C Comments
Limitations of Regular Expressions
Regular expressions cannot describe:
- Nested structures: Balanced parentheses
(()())— requires counting - Cross-references: Matching brackets
a^n b^n - Context-dependent patterns: Some token ambiguities
These require context-free grammars (handled by the parser).
Interview Questions
- What are the three fundamental operations of regular expressions?
Concatenation (ab — a followed by b), alternation (a|b — a or b), and Kleene closure (a* — zero or more repetitions of a). All other operations can be derived from these three.
- Why are regular expressions sufficient for lexical analysis but not parsing?
Regular expressions can describe flat, non-nested patterns (identifiers, numbers, operators) but cannot describe recursive structures (nested parentheses, matching brackets). Programming language syntax requires context-free grammars for describing nesting and recursion.
- What is a regular definition? Give an example.
A regular definition names a regular expression for use in other definitions. Example: digit = [0-9], integer = digit+, float = digit+ . digit+. This makes complex patterns readable and maintainable.
- **Explain the difference between
a*,a+, anda?.**
a* matches zero or more a's (ε, a, aa, ...), a+ matches one or more a's (a, aa, ...), and a? matches zero or one a (ε or a). Note: a+ = aa* and a? = a|ε.
- How do you convert a regular expression into a recognizer?
Using Thompson's construction to build an NFA, then the subset construction algorithm to convert the NFA into a DFA, and optionally DFA minimization. The resulting DFA is implemented as a transition table for efficient pattern matching.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Regular Expressions in Compiler Design.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Compiler Design topic.
Search Terms
compiler-design, compiler design, compiler, design, lexical, analysis, regular, expressions
Related Compiler Design Topics