Sto creando un compilatore con Lex e YACC (in realtà Flex e Bison). La lingua consente illimitati riferimenti in avanti a qualsiasi simbolo (come C#). Il problema è che è impossibile analizzare la lingua senza sapere cosa sia un identificatore.Come implementare i riferimenti avanzati in un compilatore?
L'unica soluzione che conosco è quello di lex l'intera sorgente, e poi fare un "breadth-first" analizzare, le cose di livello così alti come dichiarazioni di classe e le dichiarazioni di funzioni vengono analizzati prima che le funzioni che li utilizzano. Tuttavia, questo richiederebbe una grande quantità di memoria per i file di grandi dimensioni, e sarebbe difficile da gestire con YACC (dovrei creare grammatiche separate per ogni tipo di dichiarazione/corpo). Dovrei anche scrivere a mano il lexer (che non è un gran problema).
Non mi interessa un sacco di efficienza (anche se è ancora importante), perché ho intenzione di riscrivere il compilatore in sé una volta che l'ho finito, ma voglio che quella versione sia veloce (quindi se ci sono tecniche generali veloci che non possono essere fatte in Lex/YACC ma possono essere fatte a mano, per favore suggerirle anche). Quindi, al momento, la facilità di sviluppo è il fattore più importante.
Esistono buone soluzioni a questo problema? Come si fa di solito in compilatori per linguaggi come C# o Java?
Non ha nulla a che fare con le parole chiave. È più simile a questo: è ABC (pacchetto AB). (Classe C), (pacchetto A). (Classe B). (Campo C) o (campo A). (Campo B). (Campo C), ecc. – Zifre
Quindi si applica il secondo paragrafo della mia risposta. Non è necessario saperlo per analizzare. Trattare '.' come operatore nella tua grammatica. Nei tuoi passaggi AST puoi quindi controllarli contro la tabella dei simboli. – U62
Beh, suppongo che dovrò semplicemente creare un albero di analisi piuttosto che un AST. Come hai detto sono diversi. Se nessun altro ha una risposta migliore lo accetto, ma preferirei non farlo in questo modo ... – Zifre