Recursive Descent by Code Parser — Las 7 reglas para traducir una gramática BNF a código
El parser es un chef que sigue una receta (la gramática). Cada producción es una instrucción. El chef lee los ingredientes disponibles (tokens) y decide qué hacer.
A ::= B
void A() { B(); }
B ::= a
void B() { Expect(a); }
A ::= α₁ α₂ α₃
void A() { δ(α₁); δ(α₂); δ(α₃); }
¿Qué es δ(αᵢ)?
B ::= [a]
void B() { if(CurrentToken(a)) Expect(a); }
B ::= [A]
void B() { if(CurrentTokenInFirst(A)) A(); }
B ::= {a}
void B() { while(CurrentToken(a)) Expect(a); }
B ::= {A}
void B() { while(CurrentTokenInFirst(A)) A(); }
A ::= a | b | c
void A() { if(CurrentToken(a)) Expect(a); else if(CurrentToken(b)) Expect(b); else if(CurrentToken(c)) Expect(c); }
A ::= B | C | D
void A() { if(CurrentTokenInFirst(B)) B(); else if(CurrentTokenInFirst(C)) C(); else if(CurrentTokenInFirst(D)) D(); }
InstrAdvance ::= ADVANCE Num | GOBACK
void InstrAdvance() { if(CurrentToken(ADVANCE)) { Expect(ADVANCE); // R2 Expect(NUM); // R2 } else if(CurrentToken(GOBACK)) Expect(GOBACK); // R2 }
| Regla | BNF | Estructura | Keyword clave |
|---|---|---|---|
| R1 | A ::= B | B() | llamada |
| R2 | B ::= a | Expect(a) | Expect |
| R3 | A ::= α₁ α₂ | δ(α₁); δ(α₂) | secuencia |
| R4 | B ::= [a] | if(CurrentToken(a)) | if |
| R5 | B ::= {a} | while(CurrentToken(a)) | while |
| R6 | A ::= a | b | if...else if... | if-else if |
| R7 | combinación | mezcla de R1–R6 | combinar |