/* Esercizio di preparazione prova 30-5-2005 */ #include #include #include #include #include #include #include /* Tabella dei simboli */ /* NON FUNZIONA!!! LA TABELLA NON VIENE CREATA (E VISUALIZZATA) CORRETTAMENTE */ /* Utilizza la funzione getToken del programma Scanner, che per comodità è stata inserita in un file header con tutte le variabili dichiarate. Tale file si chiama ScannerLib.h e viene incluso all'inizio del programma Ricordiamo che nello scanner abbiamo definito: - int getToken(FILE*,Token*) - typedef enum {Identificatore, ParolaChiave,..} TipoToken - typedef char String[MAX_LUNG_STRINGA+1] - typedef struct {TipoToken classe; String valore;} Token */ /* Istruzioni: Preparare un file con un programma pascal. Es: ProgrammaTest.pas Creare l'eseguibile per questo programma. Es: Symbol.exe Salvare entrambi in una directory. Esempio: c: Dal prompt di Ms-Dos lanciare "c:\> Symbol ProgrammaTest.pas" */ #define HASHSIZE 127 /* si suppone che ci siano max 100 identificatori. Si aumenta di un 20%. Si prende il numero primo immediatamente superiore a 120 */ int main(int argc, char* argv[]) { int hash(Token*,Token* *); /* prototipo della funzione che crea dinamicamente la tabella dei simboli */ char* nomeFile = argv[1]; /* Il mome del file è inserito come secondo parametro di esecuzione Es: Scanner.exe TestFile.txt Scanner.exe equivale a argv[0] e TestFile.txt equivale a argv[1] */ FILE* sorgentePtr; Token token; Token* TabSimboli[HASHSIZE]; sorgentePtr = fopen(nomeFile,"r"); if (sorgentePtr == NULL) { printf("Errore di apertura file\n"); return -1; } /* Codice inserito per visualizzare tutti gli identificatori recuperati da getToken e dimostrare che getToken funziona correttamente e che il problema è la funzione Hash */ /* ------------------------------------------------------------ */ printf("\nIdentificatori individuati da getToken\n\n"); while (getToken(sorgentePtr, &token)) if (token.classe == Identificatore) printf("%s\n",token.valore); /* ------------------------------------------------------------- */ while (getToken(sorgentePtr, &token)) if (token.classe == Identificatore) hash(&token,TabSimboli); printf("\n\n\nTabella dei simboli\n"); printf("Indice Valore"); for (int i = 0; i < HASHSIZE; i++) printf("%-d\t%s\n",i,TabSimboli[i]->valore); fclose(sorgentePtr); system("PAUSE"); } int hash(Token* t,Token* vet_t[]) { int hashval; /* contiene il valore hash calcolato a seconda del token estratto */ int posizionato = 0; /* vale 1 quando si è trovato un posto libero nella tabella */ int i = 0; for (hashval = 0; t->valore[i] != '\0'; i++) hashval = t->valore[i] + 31 * hashval; /* è la funzione hash scelta */ hashval = hashval % HASHSIZE; /* si fa in modo che il numero calcolato sia un indice della tabella */ if(vet_t[hashval]->valore == NULL) { vet_t[hashval] = t; posizionato = 1; /* trovato il posto libero al primo colpo */ } else { i = hashval + 1; while (posizionato == 0 && i <= HASHSIZE) { if (vet_t[i]->valore == NULL) { vet_t[i] = t; posizionato = 1; } i++; /* si scandisce la tabella da hashval+1 fino alla fine (a meno che nel frattempo non si trova una cella libera */ } if (posizionato == 0) { /* si è usciti dal while perchè si è raggiunta la fine della tabella */ for (i = 0; i < hashval; i++) { if(vet_t[i]->valore == NULL) { vet_t[i] = t; posizionato = 1; } /* si scandisce la tabella dall'inizio fino alla posizione hashval (a meno che nel frattempo non si trova un posto libero */ } } if (posizionato == 0) printf("Tabella piena\n"); /* l'elemento non è stato posizionato nella tabella perchè non si è mai trovata una cella libera. La tabella è piena */ } return 0; }