Key Code Examples
expr โ expr + term | expr โ term | term
term โ term ร factor | term รท factor | factor
factor โ ( expr ) | number
def expr():
node = term()
while peek() in ('+', '-'):
op = consume()
node = BinOp(op, node, term())
return node
t1 = b * c
t2 = a + t1
NUMBER: [0-9]+(\.[0-9]+)?
IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*
OPERATOR: \+|โ|\*|/|=|<|>|<=|>=|==|!=
FIRST(expr) = { (, number, id }
FOLLOW(expr) = { $, ), +, โ }
FIRST(term) = { (, number, id }
FOLLOW(term) = { +, โ, $ ) }
Core Concepts
Lexical Analysis (scanning) โ Syntax Analysis (parsing) โ Semantic Analysis โ Intermediate Code Generation โ Code Optimization โ Code Generation. Each phase transforms the source representation toward machine code.
The scanner groups characters into tokens (keywords, identifiers, operators, literals). Implemented using regular expressions and finite automata (DFA/NFA). Tools: Lex, Flex.
Parsers build a parse tree/AST from tokens according to grammar rules. Top-down: Recursive Descent, LL(k). Bottom-up: LR(0), SLR(1), LALR(1), LR(1). Tools: Yacc, Bison, ANTLR.
Type checking, scope resolution, and attribute evaluation ensure the program's meaning is valid. Uses symbol tables and attribute grammars. Catches errors like undeclared variables and type mismatches.
Intermediate-level (peephole, constant folding, dead code elimination) and machine-level (loop unrolling, register allocation, instruction scheduling). Goal: faster execution, less memory, lower power.
Core Definitions
Worked Examples
Input: 3 + 4 ร 5
expr โ term { (+|โ) term } โ 3 + term โ 3 + factor { (ร|รท) factor } โ 3 + 4 ร 5
AST: (+ 3 (* 4 5)). Evaluates to 23 (multiplication has higher precedence).
Original: E โ E + T | T
Rewritten: E โ T E'
E' โ + T E' | ฮต
This allows top-down parsing without infinite recursion.
Source: x = (a + b) ร (c โ d)
t1 = a + b
t2 = c โ d
t3 = t1 ร t2
x = t3
Each instruction has at most three operands โ easily translated to assembly.
Practice Problems
Answer: [a-zA-Z_][a-zA-Z0-9_]*
Answer: The DFA has 3 states: {q0} (start), {q0,q1}, {q0,q1,q2} (accept). Transitions track last two symbols.
Answer: A โ ฮฒ A'; A' โ ฮฑ A' | ฮต
Answer: t1 = a * b; t2 = c * d; t3 = t1 + t2; y = t3 + e
Answer: SLR uses FOLLOW sets for lookahead (larger state sets, more conflicts). LALR merges LR(1) states with identical cores โ smaller tables than LR(1), fewer conflicts than SLR. Same power: LALR โ LR(1), LALR โ SLR.