I tokenizer separati sono un dettaglio di implementazione dei parser. Non sono necessari tokenizer separati; è possibile creare parser senza tokenizer separati.
Tuttavia, i tokenizer separati sono spesso usati nella pratica e, quando lo sono, i token vengono spesso definiti usando (reale) regolare espressioni.
Se utilizzi un tokenizzatore separato, potresti trovare difficile o impossibile passare a tokenizer nel corso di un'analisi. Tuttavia, non ci sono problemi teorici con questo, solo tecnologico: se si sceglie la tecnologia giusta, in realtà è abbastanza facile da fare.
Quindi, per rispondere alle tue domande specifiche:
- "Una grammatica che cambierebbe il suo tokenizer a metà analisi è stata definita da qualche parte?" Questo può accadere con la composizione del linguaggio. I tokenizer separati e regolari non interagiscono bene con la composizione del linguaggio.
- "Una grammatica definisce anche una cosa del genere o è irrilevante per la grammatica e non viene realmente eseguita a livello di parser?" La tokenizzazione fa parte di una grammatica, quindi sì, una grammatica è libera di dettare come avviene la tokenizzazione a seconda della regola che sta tentando di analizzare. Tuttavia, potresti non vederlo spesso nella pratica. In genere, almeno nella mia esperienza, la tokenizzazione è regolare e non contestuale o sensibile al contesto.