Lex vs Yacc: Confronto tra Analizzatore Lessicale e Generatore di Parser
Strumenti per la Costruzione di Compilatori: Lex e Yacc Spiegati
Lex e Yacc sono strumenti Unix fondamentali per la costruzione di compilatori e interpreti. Gestiscono fasi sequenziali dell'elaborazione del linguaggio.
Lex — Generatore di Analizzatore Lessicale
- Input: Espressioni regolari (pattern per token)
- Output: Programma C (
lex.yy.c) = lesser/scanner - Funzione: Flusso di caratteri → Flusso di token
- Token: Parole chiave, identificatori, letterali, operatori, punteggiatura
- Deterministico: Conosce sempre il prossimo token (basato su DFA)
- Più semplice: Più facile da imparare, scrivere, debuggare
Yacc — Yet Another Compiler-Compiler (Generatore di Parser)
- Input: Grammatica libera dal contesto (regole simili a BNF)
- Output: Programma C (
y.tab.c) = parser - Funzione: Flusso di token → Albero di sintassi / AST
- Parsing: LALR(1) — bottom-up, lookahead 1
- Non deterministico: Può fare backtrack/risolvere conflitti (shift/reduce, reduce/reduce)
- Complesso: Progettazione grammatica, risoluzione conflitti, regole di precedenza
Flusso di Lavoro
[Codice Sorgente] → [Lex] → [Token] → [Yacc] → [Albero di Sintassi] → [Analisi Semantica] → [Generazione Codice] Differenze Chiave
| Aspetto | Lex | Yacc |
|---|---|---|
| Fase | Analisi lessicale (scansione) | Analisi sintattica (parsing) |
| Formalismo | Espressioni regolari | Grammatica libera dal contesto |
| Output | Token (simboli terminali) | Gerarchia strutturata (AST) |
| Complessità | Bassa | Alta |
| Determinismo | Sì (DFA) | No (LALR con conflitti) |
| Gestione Errori | Carattere non valido | Recupero da errore di sintassi |
Successori Moderni
- Flex (GNU Lex) + Bison (GNU Yacc) — standard su Linux
- ANTLR — grammatica unificata, LL(*), multi-target (Java, Python, JS, C++)
- Tree-sitter — parsing incrementale per IDE
Lex/Yacc rimangono il fondamento pedagogico per comprendere le pipeline di elaborazione del linguaggio.