home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / compcomp / tpyacc / yreftabl.pas < prev    next >
Pascal/Delphi Source File  |  1991-03-05  |  5KB  |  196 lines

  1.  
  2. unit YRefTables;
  3.  
  4. (* This module implements the symbol and cross reference table used
  5.    by the YREF program. *)
  6.  
  7. interface
  8.  
  9. const
  10.  
  11. max_syms = 997; (* symbol table size (prime number!) *)
  12.  
  13. function lookup ( k : Integer ) : String;
  14. procedure entry ( k : Integer; symbol : String );
  15. (* lookup and entry routines for the symbol table *)
  16.  
  17. procedure add_ref ( k : Integer; lineno : Integer; mark : Boolean );
  18.   (* Enter an occurrence for symbol k into the table; the mark flag indicates
  19.      whether this occurrence should be marked as a "defining" occurrence. *)
  20.  
  21. procedure set_type ( k : Integer; t : Integer );
  22.   (* set the type of symbol k *)
  23.  
  24. procedure ref_list;
  25.   (* Produces the cross reference listing in alphabetical order. *)
  26.  
  27. var n_undef : Integer;
  28.   (* number of undefined symbols *)
  29.  
  30. implementation
  31.  
  32. uses LexLib, YRefTools;
  33.  
  34. (* Basic data structures and routines: *)
  35.  
  36. type
  37.  
  38. StrPtr  = ^String;               (* dynamic strings *)
  39. RefList = ^RefNode;              (* symbol occurrence lists *)
  40. RefNode = record
  41.             lineno : Integer;    (* line number *)
  42.             mark   : Boolean;    (* mark flag *)
  43.             next   : RefList;    (* link to next list element *)
  44.           end;
  45.  
  46. function newStr ( str : String ) : StrPtr;
  47.   (* returns a dynamic copy of str (only the number of bytes actually
  48.      needed are allocated) *)
  49.   var strp : StrPtr;
  50.   begin
  51.     getmem(strp, succ(length(str)));
  52.     move(str, strp^, succ(length(str)));
  53.     newStr := strp;
  54.   end(*newStr*);
  55.  
  56. procedure append ( var L : RefList; lineno : Integer; mark : Boolean );
  57.   (* append an entry to the given occurrence list (eliminate dups) *)
  58.   begin
  59.     if L=nil then
  60.       begin
  61.         new(L);
  62.         L^.lineno := lineno;
  63.         L^.mark   := mark;
  64.         L^.next   := nil;
  65.       end
  66.     else if L^.lineno=lineno then
  67.       L^.mark := L^.mark or mark
  68.     else
  69.       append(L^.next, lineno, mark);
  70.   end(*append*);
  71.  
  72. (* Symbol and cross reference table: *)
  73.  
  74. var
  75.  
  76. sym_table : array [1..max_syms] of StrPtr;  (* symbol table (nil denotes
  77.                                                empty entry) *)
  78. ref_table : array [1..max_syms] of RefList; (* cross reference table *)
  79.  
  80. defined   : array [1..max_syms] of Boolean; (* defined symbols *)
  81.  
  82. sym_type  : array [1..max_syms] of Integer; (* symbol types *)
  83.  
  84. n_syms    : Integer;                        (* number of symbols in the
  85.                                                table *)
  86. sym_no    : array [1..max_syms] of Integer; (* symbol keys sorted in
  87.                                                alphabetical order *)
  88.  
  89. (* Comparison and swap routines to sort the symbol table: *)
  90.  
  91. {$F+}
  92. function sym_less ( i, j : Integer ) : Boolean;
  93. {$F-}
  94.   begin
  95.     sym_less := sym_table[sym_no[i]]^<sym_table[sym_no[j]]^
  96.   end(*sym_less*);
  97.  
  98. {$F+}
  99. procedure sym_swap ( i, j : Integer );
  100. {$F-}
  101.   var x : Integer;
  102.   begin
  103.     x := sym_no[i]; sym_no[i] := sym_no[j]; sym_no[j] := x;
  104.   end(*sym_swap*);
  105.  
  106. procedure sort;
  107.   (* sort symbols into sym_no array *)
  108.   var k : Integer;
  109.   begin
  110.     n_syms := 0;
  111.     for k := 1 to max_syms do
  112.       if (sym_table[k]<>nil) and (ref_table[k]<>nil) then
  113.         begin
  114.           inc(n_syms);
  115.           sym_no[n_syms] := k;
  116.         end;
  117.     quicksort(1, n_syms, sym_less, sym_swap);
  118.   end(*sort*);
  119.  
  120. (* Interface routines: *)
  121.  
  122. function lookup ( k : Integer ) : String;
  123.   begin
  124.     if sym_table[k]=nil then
  125.       lookup := ''
  126.     else
  127.       lookup := sym_table[k]^
  128.   end(*lookup*);
  129.  
  130. procedure entry ( k : Integer; symbol : String );
  131.   begin
  132.     sym_table[k] := newStr(symbol)
  133.   end(*entry*);
  134.  
  135. procedure add_ref ( k : Integer; lineno : Integer; mark : Boolean );
  136.   begin
  137.     append(ref_table[k], lineno, mark);
  138.     defined[k] := defined[k] or mark;
  139.   end(*add_ref*);
  140.  
  141. procedure set_type ( k : Integer; t : Integer );
  142.   begin
  143.     sym_type[k] := t;
  144.   end(*set_type*);
  145.  
  146. procedure ref_list;
  147.   const tab = #9;
  148.   var i : Integer;
  149.       L : RefList;
  150.   begin
  151.     sort;
  152.     writeln(yyoutput);
  153.     for i := 1 to n_syms do
  154.       begin
  155.         write(yyoutput, '  ', sym_table[sym_no[i]]^);
  156.         if sym_type[sym_no[i]]<>0 then
  157.           write(yyoutput, ' <', sym_table[sym_type[sym_no[i]]]^, '>');
  158.         write(yyoutput, ' ');
  159.         L := ref_table[sym_no[i]];
  160.         while L<>nil do
  161.           with L^ do
  162.             begin
  163.               write(yyoutput, ' ', lineno);
  164.               if mark then write(yyoutput, '*');
  165.               L := next;
  166.             end;
  167.         writeln(yyoutput);
  168.       end;
  169.     n_undef := 0;
  170.     for i := 1 to n_syms do
  171.       if not defined[sym_no[i]] and
  172.          (sym_table[sym_no[i]]^<>'error') then
  173.         inc(n_undef);
  174.     if n_undef>0 then
  175.       begin
  176.         writeln(yyoutput);
  177.         writeln(yyoutput, '  undefined symbols:');
  178.         writeln(yyoutput);
  179.         for i := 1 to n_syms do
  180.           if not defined[sym_no[i]] and
  181.              (sym_table[sym_no[i]]^<>'error') then
  182.             writeln(yyoutput, '  ', sym_table[sym_no[i]]^);
  183.       end;
  184.   end(*ref_list*);
  185.  
  186. var k : Integer;
  187. begin
  188.   for k := 1 to max_syms do
  189.     begin
  190.       sym_table[k] := nil;
  191.       ref_table[k] := nil;
  192.       defined[k]   := false;
  193.       sym_type[k]  := 0;
  194.     end;
  195. end(*YRefTables*).
  196.