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
SymbolTable
sarebbe unhash_map
di qualche tipo usando i lexeme s come chiavi. Cioèstring
tipi. Ho determinato da solo che il suo valore sarebbe una tupla contenenteSYMBOL_TYPE
e un puntatore / riferimento / ricerca a un secondoarray
che contiene le informazioni aggiuntive necessarie per questoSYMBOL_TYPE
.vale a dire. una voce in
SymbolTable
potrebbe essere<SYMBOL_TYPE::VARIABLE,3>
che significherebbe che l'arrayVariables
all'indice3
sarà caratterizzato da queste variabilitype
+value
+attributes
.Quindi farei lo stesso per altri identificatori come le procedure ecc.
-
Il
Lexer
passa 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
SymbolTable
stesso 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
Lexer
ha prodotto un token, aggiunge nuovi identificatori alla tabella dei simboli? Come fa a sapere se questo dovrebbe essere unSYMBOL_TYPE::FUNCTION
oSYMBOL_TYPE:::VARIABLE
? Oppure lo popola solo conSYMBOL_TYPE::ID
e consenti aParser
di aggiornare successivamente la voce una volta determinato l'utilizzo degli identificatori?Penso che non possa essere lasciato a
Parser
perché quando un nuovo scope viene avviato dal verificarsi di un{
, ilLexer
dovrebbe aggiungere un nuovoSymbolTable
a uno stack altrimenti ilToken
ritorna allaParser
punterebbe alla voce sbagliata ... Ma poi non ci si può aspettare cheLexer
aggiunga le informazionitype
evalue
aVariables
oProcedures
matrici. -
La
Parser
richiede ogniToken
a sua volta daLexer
.Domanda 3 : che cosa è esattamente necessario in questo tipo di
Token
che viene restituito? Al momento è solo ilSYMBOL_TYPE
+ l'indice inSymbolTable
. IlSymbolTable
quindi si collega al% aggiuntivo aggiuntivo% co_de per quellist
. Ma dovrebbe essere qualcosa di diverso daSYMBOL_TYPE
, comeSYMBOL_TYPE
e consentire aTOKEN_TYPE
di aggiungersi alParser
piuttosto che alSymbolTable
? PoichéLexer
non può determinare se un identificatore è unLexer
ovariable
. Poichéprocedure
deve aggiungerli a causa di ambiti diversi, ilLexer
elimina quindi ciò cheParser
ha 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
?