home *** CD-ROM | disk | FTP | other *** search
- FUNCTION Hash(VAR Symbol : Symbol_Type;
- Hash_size : INTEGER) : INTEGER;
- {
- This function returns the hash code for a particular symbol given the hash size.
- }
-
- VAR
- String_length, Key : INTEGER;
-
- BEGIN
- String_length := LENGTH(Symbol);
- IF String_length = 1 THEN
- Key := ORD(Symbol[1])
- ELSE
- IF String_length < 4 THEN
- Key := ORD(Symbol[1])*100 + ORD(Symbol[2])
- ELSE
- Key := ORD(Symbol[1])*100 + ORD(Symbol[String_length DIV 2 + 1]);
- Hash := Key MOD Hash_size + 1;
- END;
-
- PROCEDURE Find_Symbol(VAR Symbol : Symbol_Type;
- VAR Hash_table_pntr, Chain_table_pntr, Symbol_table_pntr;
- Hash_size : INTEGER;
-
- VAR Found : BOOLEAN;
- VAR Index : INTEGER);
- {
- This routine searches for a given symbol in the given hashed symbol table and,
- if it is found, returns Found = TRUE and its index in the symbol table.
- Symbol is the symbol to store. Hash_table_pntr is the table to hash to; its
- contents point to positions in the Symbol_table and in the Chain_table (denoted
- formally by Symbol_table_pntr and Chain_table_pntr, respectively). If a symbol
- hashes to the same location in the Hash_table, then it will exist in the symbol
- table along the links established by the Chain_table. Only the addresses of
- the hash, chain, and symbol tables are passed so that variable-length data
- structures are accommodated.
- }
-
- TYPE
- Hash_Table_Type = ARRAY[1..Max_Hash_size] OF INTEGER;
- Chain_Table_Type = ARRAY[1..Max_Table_size] OF INTEGER;
- Symbol_Table_Type = ARRAY[1..Max_Table_size] OF STRING[Max_word_length];
-
- VAR
- Hash_table : Hash_Table_Type ABSOLUTE Hash_table_pntr;
- Chain_table : Chain_Table_Type ABSOLUTE Chain_table_pntr;
- Symbol_table : Symbol_Table_Type ABSOLUTE Symbol_table_pntr;
-
- BEGIN
- Index := Hash_table[Hash(Symbol, Hash_size)];
- IF Index = 0 THEN
- Found := FALSE
- ELSE
- BEGIN
- WHILE (Symbol <> Symbol_table[Index]) AND (Chain_table[Index] <> 0) DO
- Index := Chain_table[Index];
- Found := Symbol = Symbol_table[Index];
- END;
- END;
-
- PROCEDURE Store_Symbol(VAR Symbol : Symbol_Type;
- VAR Hash_table_pntr, Chain_table_pntr, Symbol_table_pntr;
- Hash_size : INTEGER;
- Check_first : BOOLEAN;
- VAR Count : INTEGER);
- {
- This routine stores a symbol in the given hashed symbol table. See comments in
- the procedure: Find_Symbol. Count is the current number of entries in the
- tables. Only the addresses of the hash, chain, and symbol tables are passed
- so that variable-length data structures are accommodated.
- }
-
- TYPE
- Hash_Table_Type = ARRAY[1..Max_Hash_size] OF INTEGER;
- Chain_Table_Type = ARRAY[1..Max_Table_size] OF INTEGER;
- Symbol_Table_Type = ARRAY[1..Max_Table_size] OF STRING[Max_word_length];
-
- VAR
- Hash_table : Hash_Table_Type ABSOLUTE Hash_table_pntr;
- Chain_table : Chain_Table_Type ABSOLUTE Chain_table_pntr;
- Symbol_table : Symbol_Table_Type ABSOLUTE Symbol_table_pntr;
- Index : INTEGER;
- Found : BOOLEAN;
-
- BEGIN
- IF Check_first THEN
- BEGIN
- Find_Symbol(Symbol, Hash_table, Chain_table, Symbol_table, Hash_size,
- Found, Index);
- IF Found THEN EXIT; {If it is already in the table, don't enter it again}
- END;
- Count := Count + 1;
- IF Count > Max_Table_size THEN
- BEGIN
- Writeln('Error: Hash Table Overflow!');
- HALT;
- END;
- Symbol_table[Count] := Symbol; {Store in symbol table}
- Index := Hash(Symbol, Hash_size);
- IF Hash_table[Index] = 0 THEN
- Chain_table[Count] := 0 {Start new chain}
- ELSE
- Chain_table[Count] := Hash_table[Index]; {Insert in chain}
- Hash_table[Index] := Count; {Store in hash table}
- END;