File XREF45.PS

Directory of image this file is from
This file as a plain text file

program Crossref45(source,listing) {1981-03-29};

{ Simple cross reference generator for Pascal programs, using
  a binary tree. John Easton, SSRFC, U of M, 1981.

  Limitations:

    -- amount of memory available limits the size of source text processable.
    -- Pascal reserved words are not suppressed.
    -- upper-lower case are completely distinct; mixed case names that
       are spelled the same won't match.

  This program exists as a reference for the algorithm EnterID.
  It can process correct Pascal programs, but there exist more complete cross
  reference generators.

  Adapted from Niklaus Wirth's program 4.5 in 'Algorithms + Data Structures =
  Programs', Prentice Hall 1976, section 4.4, pp 206-208.

  Please retain the above names in all uses of this program.
}

  const
    idstrlength =     10  {length of identifiers};
    tablewidth =      70  {cross-reference table};
    {width of listing is not limited}
    digitspernumber =  5;

  type
    idstring = packed array [1..idstrlength] of char;
    natural =  0..maxint;
    entryptr =	^ entry;
    refptr =  ^ reference;

    entry =
      record
	key: idstring;
	left, right: entryptr;
	last: refptr {last reference points to first}
      end	     {reference in a circular list};

    reference =
      packed record
	lno: natural;
	next: refptr
      end;

  var
    source, listing: text;
    root:   entryptr;
    refsperline: natural;

  procedure Scan(var f: text);
    var
      lastidlength: 0..idstrlength;
      id:	    idstring;
      linenumber:   natural  {current source line number};

    procedure EnterID(id: idstring; var w1: entryptr);

      procedure Enter(var w1: entryptr);
	var
	  w: entryptr;
	  x: refptr;
      begin {Enter}
	w := w1;
	if w = nil then
	  begin
	    new(w);   new(x);
	    with w^ do
	      begin
		key := id;
		left := nil;   right := nil;
		last := x
	      end;
	    x^.lno := linenumber;
	    x^.next := x {circular list};
	    w1 :=w
	  end
	else if id < w^.key then Enter(w^.left)
	else if id > w^.key then Enter(w^.right)
	else
	  begin
	    new(x);
	    x^.lno := linenumber;   x^.next := w^.last^.next;
	    w^.last^.next := x;     w^.last := x
	  end
      end {Enter};

    begin {EnterID}
      Enter(w1)
    end {Enter ID};

    procedure OpenLine;
    begin {OpenLine}
      linenumber := linenumber + 1;
      write(listing,linenumber:digitspernumber,' ')
    end {OpenLine};

    procedure NextCH;
    begin {NextCH}
      if eoln(f) then
	begin writeln(listing); OpenLine end
      else write(listing,f^);
      get(f)
    end {NextCH};

    procedure ScanIdent;
      var idlen: 0..idstrlength;
    begin {ScanIdent}
      idlen := 0;
      repeat
	if idlen < idstrlength then
	  begin
	    idlen := idlen + 1;
	    id[idlen] := f^
	  end;
	write(listing,f^);
	get(f)
      until not (f^ in ['A','B','C','D','E','F','G','H','I','J','K','L','M',
			'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
			'a','b','c','d','e','f','g','h','i','j','k','l','m',
			'n','o','p','q','r','s','t','u','v','w','x','y','z',
			'0'..'9']);
      if idlen >= lastidlength then lastidlength := idlen
      else
	repeat
	  id[lastidlength] := ' ';
	  lastidlength := lastidlength - 1
	until lastidlength = idlen;
      EnterID(id,root)
    end {ScanIdent};

    procedure ScanQuote;
    begin {ScanQuote}
      repeat
	write(listing,f^);
	get(f)
      until f^ = '''';
      NextCH
    end {ScanQuote};

    procedure ScanComment;
    begin {ScanComment}
      NextCH;
      repeat
	while not (f^ in ['*','}']) do NextCH;
	if f^ = '*' then NextCH
      until f^ in [')','}'];
      NextCH
    end {ScanComment};

  begin {Scan}
    linenumber := 0;  lastidlength := idstrlength;
    while not eof(f) do
      begin
	OpenLine;
	while not eoln(f) do
	  begin
	    if f^ = ' ' then {very frequent}
	      begin write(listing,f^); get(f) end
	    else if f^ in ['A','B','C','D','E','F','G','H','I','J','K','L','M',
			   'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
			   'a','b','c','d','e','f','g','h','i','j','k','l','m',
			   'n','o','p','q','r','s','t','u','v','w','x','y','z'
			  ] then ScanIdent
	    else if f^ = '{' then ScanComment
	    else if f^ = '(' then
	      begin NextCH; if f^ = '*' then ScanComment end
	    else if f^ = '''' then ScanQuote
	    else {all other chars}
	      begin write(listing,f^); get(f) end
	  end {while not eoln(f)};
	writeln(listing); get(f) {readln(f)}
      end {while not eof(f)}
  end {Scan};

  procedure Printtree(w: entryptr);

    procedure PrintWord(w:entry);
      var
	c: natural;
	x: refptr;
    begin {PrintWord}
      write(listing,' ',w.key);
      x := w.last^.next;
      w.last^.next := nil {break the ring};
      c := 0;
      repeat
	if c = refsperline then
	  begin
	    writeln(listing);
	    c := 0;
	    write(listing,' ':idstrlength+1)
	  end;
	c := c + 1;
	write(listing,' ',x^.lno:digitspernumber);
	x := x^.next
      until x = nil;
      writeln(listing)
    end {PrintWord};

  begin {Printtree}
    if w <> nil then
      begin
	Printtree(w^.left);
	PrintWord(w^);
	Printtree(w^.right)
      end
  end {Printtree};

begin {crossref 4.5}
  root := nil;
  rewrite(listing);
  page(listing);
  reset(source);
  Scan(source);
  page(listing);
  refsperline := (tablewidth - idstrlength - 1) div
		 (digitspernumber + 1);
  Printtree(root)
end {crossref 4.5}.



Feel free to contact me, David Gesswein djg@pdp8online.com with any questions, comments on the web site, or if you have related equipment, documentation, software etc. you are willing to part with.  I am interested in anything PDP-8 related, computers, peripherals used with them, DEC or third party, or documentation. 

PDP-8 Home Page   PDP-8 Site Map   PDP-8 Site Search