Sto lavorando alla creazione del mio linguaggio di scripting per scopi di apprendimento. Ho letto il Libro del Drago e alcune cose mi sono un po 'oscure per quanto riguarda la Tabella dei Simboli e anche dove risiedono effettivamente le stringhe che costituiscono un identificatore e la proprietà. La maggior parte di questa confusione penso sia dovuta al libro che usa tecniche più vecchie mentre sto cercando di usare C ++ 11.
A quanto ho capito:
-
Il
SymbolTablesarebbe unhash_mapdi qualche tipo usando i lexeme s come chiavi. Cioèstringtipi. Ho determinato da solo che il suo valore sarebbe una tupla contenenteSYMBOL_TYPEe un puntatore / riferimento / ricerca a un secondoarrayche contiene le informazioni aggiuntive necessarie per questoSYMBOL_TYPE.vale a dire. una voce in
SymbolTablepotrebbe essere<SYMBOL_TYPE::VARIABLE,3>che significherebbe che l'arrayVariablesall'indice3sarà caratterizzato da queste variabilitype+value+attributes.Quindi farei lo stesso per altri identificatori come le procedure ecc.
-
Il
Lexerpassa attraverso i caratteri finché non viene prodotto il lexeme più lungo possibile ogni volta che viene richiesto il successivoToken.Domanda 1 : dove risiedono questi lessemi preesistenti? Ad esempio, se la tabella dei simboli è precompilata con parole chiave, punteggiatura, operatori, ecc., Chi la precompila? Il
SymbolTablestesso si pre-popola con un elenco di parole chiave + punteggiatura + operatori? Vorrei quindi solo tentare di abbinare ogni voce nella tabella dei simboli (iniziando con il più lungo prima)?Domanda 2 : quando
Lexerha prodotto un token, aggiunge nuovi identificatori alla tabella dei simboli? Come fa a sapere se questo dovrebbe essere unSYMBOL_TYPE::FUNCTIONoSYMBOL_TYPE:::VARIABLE? Oppure lo popola solo conSYMBOL_TYPE::IDe consenti aParserdi aggiornare successivamente la voce una volta determinato l'utilizzo degli identificatori?Penso che non possa essere lasciato a
Parserperché quando un nuovo scope viene avviato dal verificarsi di un{, ilLexerdovrebbe aggiungere un nuovoSymbolTablea uno stack altrimenti ilTokenritorna allaParserpunterebbe alla voce sbagliata ... Ma poi non ci si può aspettare cheLexeraggiunga le informazionitypeevalueaVariablesoProceduresmatrici. -
La
Parserrichiede ogniTokena sua volta daLexer.Domanda 3 : che cosa è esattamente necessario in questo tipo di
Tokenche viene restituito? Al momento è solo ilSYMBOL_TYPE+ l'indice inSymbolTable. IlSymbolTablequindi si collega al% aggiuntivo aggiuntivo% co_de per quellist. Ma dovrebbe essere qualcosa di diverso daSYMBOL_TYPE, comeSYMBOL_TYPEe consentire aTOKEN_TYPEdi aggiungersi alParserpiuttosto che alSymbolTable? PoichéLexernon può determinare se un identificatore è unLexerovariable. Poichéproceduredeve aggiungerli a causa di ambiti diversi, ilLexerelimina quindi ciò cheParserha aggiunto e ne aggiunge il proprio?
Sono confuso riguardo a chi possiede la creazione e la gestione di Lexer e se gli identificativi in esso devono essere uguali a quelli che sono passati tra SymbolTable e Lexer .
Mi sembra che sarebbe più semplice avere il Parser restituire solo Lexer che determina se si tratta di una parola chiave / operatore / punteggiatura conosciuta (ciascuno con il proprio Tokens ) + il TOKEN_TYPE che rende it up (se necessario) e string quindi aggiunge voci a Parser e successivi array (come l'array SymbolTable ) quando è necessario. Verrà anche visualizzato un Variables e aggiungere una nuova { allo stack quando necessario.
Sto interpretando male l'obiettivo di SymbolTable ?