CFG
CFG
Specification for the parser written in CFG
↓
|-------------|
Focus: | Parser |
| Synthesizer |
|-------------|
|
synthesizes
↓
|--------|
a sequence of tokens → | Parser | → parse tree
|--------|
Q: How can we turn a CFG into a parse tree?
start : exp EOF
exp: INT | ID | exp PLUS exp | '(' exp ')'
A -> X Y Z
A
/|\
X Y Z
// Grammar G
E : E '+' E | int
int '+' int
?// Grammar G
E : E '+' E | int
input: int '+' int
E → .... → E
/|\
E + E
| |
int int
The rightmost nonterminal is replaced.
// Grammar G
E : E '+' E | int
input: int '+' int
// Grammar G
E : E '+' E | int
input: int '+' int
E -lm-> E '+' E -lm-> int '+' E -lm-> int '+' int
E → E → E → E
/|\ /|\ /|\
E + E E + E E + E
| | |
int int int
// Grammar G
E : E '+' E | int
input: int '+' int
E -rm-> E '+' E -rm-> E '+' int -rm-> int '+' int
E → E → E → E
/|\ /|\ /|\
E + E E + E E + E
| | |
int int int
|--------| |--------|
input → | Lexer | → sequence of tokens → | Parser | → parse tree
|--------| |--------|
|--------| |--------|
input → | Lexer | → current token → | Parser |
|--------| |--------|
↑ ↓
| intermediate
← request the next token ← incomplete
parse tree
|--------| |--------|
input → | Lexer | → sequence of tokens → | Parser | → parse tree
|--------| |--------|
|--------| |--------|
input → | Lexer | → current token → | Parser |
|--------| |--------|
↑ ↓
| intermediate
← request the next token ← incomplete
parse tree
// Grammar G
E : E '+' E | int
input: int '+' int
↑
E → E
/|\
E + E
// Grammar G
E : E '+' E | int
input: int '+' int
↑
E → E → E
/|\ /|\
E + E E + E
|
int
// Grammar G
E : E '+' E | int
input: int '+' int
↑
E → E → E → E
/|\ /|\ /|\
E + E E + E E + E
| | |
int int int
// Grammar G
E : E '+' E | int
input: int '+' int
↑
E → E → E
/|\ /|\
E + E E + E
|
int
int
yet!// Grammar G
E : E '+' E | int
input: int '+' int
E
/ | \
E E E E | E
| | | | | |
int '+' int → int '+' int → int '+' int
↑ ↑ ↑
// Grammar G
E : E '+' E | int
input: int '+' int
E
// || \\
E E E E || E
|| | || | || |
int '+' int → int '+' int → int '+' int
↑ ↑ ↑
E -rm-> E '+' E -rm-> E '+' int -rm-> int '+' int
// Grammar G
E : E '+' E | int
Top-Down parsing uses the leftmost derivation.
E → E → E → E
/|\ /|\ /|\
E + E E + E E + E
| | |
int int int
Bottom-Up parsing uses the rightmost derivation.
E
/ | \
E E E E | E
| | | | | |
int '+' int → int '+' int → int '+' int