www.pudn.com > LexYaccProgs.zip > YREFTOOL.PAS
unit YRefTools;
(* This module supplies generic hash table and quicksort routines used
by the YREF program. *)
interface
(* Quicksort: *)
type
OrderPredicate = function (i, j : Integer) : Boolean;
SwapProc = procedure (i, j : Integer);
procedure quicksort(lo, hi: Integer;
less : OrderPredicate;
swap : SwapProc);
(* General inplace sorting procedure based on the quicksort algorithm.
This procedure can be applied to any sequential data structure;
only the corresponding routines less which compares, and swap which
swaps two elements i,j of the target data structure, must be
supplied as appropriate for the target data structure.
- lo, hi: the lower and higher indices, indicating the elements to
be sorted
- less(i, j): should return true if element no. i `is less than'
element no. j, and false otherwise; any total quasi-ordering may
be supplied here (if neither less(i, j) nor less(j, i) then elements
i and j are assumed to be `equal').
- swap(i, j): should swap the elements with index i and j *)
(* Generic hash table routines (based on quadratic rehashing; hence the
table size must be a prime number): *)
type
TableLookupProc = function(k : Integer) : String;
TableEntryProc = procedure(k : Integer; symbol : String);
function key(symbol : String;
table_size : Integer;
lookup : TableLookupProc;
entry : TableEntryProc) : Integer;
(* returns a hash table key for symbol; inserts the symbol into the
table if necessary
- table_size is the symbol table size and must be a fixed prime number
- lookup is the table lookup procedure which should return the string
at key k in the table ('' if entry is empty)
- entry is the table entry procedure which is assumed to store the
given symbol at the given location *)
function definedKey(symbol : String;
table_size : Integer;
lookup : TableLookupProc) : Boolean;
(* checks the table to see if symbol is in the table *)
implementation
procedure fatal(msg : String);
(* writes a fatal error message and exits *)
begin
writeln(msg);
halt(1);
end(*fatal*);
(* Quicksort: *)
procedure quicksort(lo, hi: Integer;
less : OrderPredicate;
swap : SwapProc);
(* derived from the quicksort routine in QSORT.PAS in the Turbo Pascal
distribution *)
procedure sort(l, r: Integer);
var i, j, k : Integer;
begin
i := l; j := r; k := (l+r) DIV 2;
repeat
while less(i, k) do inc(i);
while less(k, j) do dec(j);
if i<=j then
begin
swap(i, j);
if k=i then k := j (* pivot element swapped! *)
else if k=j then k := i;
inc(i); dec(j);
end;
until i>j;
if l n^2 = (n-1)^2 + (2n-1) for n>0,
i.e. the increment inc=2n-1 increments by two in each collision *)
begin
inc(count);
inc(pos, incr);
if pos>table_size then pos := pos mod table_size + 1;
inc(incr, 2)
end(*newPos*);
function key(symbol : String;
table_size : Integer;
lookup : TableLookupProc;
entry : TableEntryProc) : Integer;
var pos, incr, count : Integer;
begin
pos := hash(symbol, table_size);
incr := 1;
count := 0;
while count<=table_size do
if lookup(pos)='' then
begin
entry(pos, symbol);
key := pos;
exit
end
else if lookup(pos)=symbol then
begin
key := pos;
exit
end
else
newPos(pos, incr, count, table_size);
fatal('symbol table overflow')
end(*key*);
function definedKey(symbol : String;
table_size : Integer;
lookup : TableLookupProc) : Boolean;
var pos, incr, count : Integer;
begin
pos := hash(symbol, table_size);
incr := 1;
count := 0;
while count<=table_size do
if lookup(pos)='' then
begin
definedKey := false;
exit
end
else if lookup(pos)=symbol then
begin
definedKey := true;
exit
end
else
newPos(pos, incr, count, table_size);
definedKey := false
end(*definedKey*);
end(*YRefTools*).