home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / TURBOPAS / PASUTIL1.ZIP / XREF.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1985-12-28  |  21.5 KB  |  607 lines

  1.  {$LINESIZE:132}
  2.  {$PAGESIZE:57}
  3.  {$LIST+}
  4.  {$symtab+}
  5.  {$WARN-} 
  6.  {$DEBUG+} 
  7.  {$LINE+}
  8.  {$ENTRY+}
  9.  {$INDEXCK-}
  10.  {$RANGECK-}
  11.  {$INITCK-}
  12.  {$INDEXCK-} 
  13. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  14. {+                                                      +}
  15. {+  PROGRAM TITLE:      Cross Reference Generator       +}
  16. {+                                                      +}
  17. {+  WRITTEN BY:         Peter Grogono                   +}
  18. {+  DATE WRITTEN:       ?                               +}
  19. {+                                                      +}
  20. {+  SUMMARY:                                            +}
  21. {+                                                      +}
  22. {+      1. Output Files:                                +}
  23. {+         default is to disk files:                    +}
  24. {+         a. output file = file name + '.XRF'          +}
  25. {+            all identifiers and their line #          +}
  26. {+         b. output file = file name + '.PRN'          +}
  27. {+            the file with all lines numbered          +}
  28. {+      2. LISTING Device:                              +}
  29. {+         Output may be to either the console or       +}
  30. {+         the printer but NOT both.                    +}
  31. {+                                                      +}
  32. {+  MODIFICATION RECORD:                                +}
  33. {+      12-AUG-80       -modified for Pascal/Z v3.0     +}
  34. {+                      -by Raymond E. Penley           +}
  35. {+      16-AUG-80       -added function ConnectFiles    +}
  36. {+      17-AUG-80       -added GetL, ReadC, ReadWord    +}
  37. {+      22-AUG-80       -selective use of control-c     +}
  38. {+                                                      +}
  39. {+                                                      +}
  40. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  41. PROGRAM XREFG2;
  42. { Cross Reference Generator }
  43. (*%P-,F-,M- [symbolic I/O OFF,
  44.              floating point checking OFF,
  45.              integer mult & div checking OFF]           *)
  46. CONST
  47.         alfa_length     =    8;
  48.         BLANKS          = '        ';
  49.         dflt_str_len    = 255;
  50.         entrygap        =    0;   { # of blank lines between line numbers}
  51.         fid_len         =   14;   { Max length CP/M file names }
  52.         heading         = 'Cross-Reference Listing';
  53.         headingsize     =    3;   {number of lines for heading}
  54.         LLmax           = dflt_str_len;
  55. {}      MaxOnLine       =   10;
  56.         Maxlines        = MAXINT; {longest document permitted}
  57.         MaxWordlen      = alfa_length;{longest word read without truncation}
  58.         Maxlinelen      =   80;   {length of output line}
  59.         MaxOnPage       =   60;   {size of output page}
  60.         numbergap       =    2;   {number of gaps between line numbers}
  61. {}      NumKeys         =   46;   {number of Pascal reseve words}
  62.                                   {Read your Pascal manuals on this one!}
  63. {}      NumKeysP1       = NumKeys + 1;
  64. {}      NumberWidth     =    6;
  65.         space           =  ' ';  
  66. TYPE
  67. {}      ALFA    = PACKED ARRAY[1..alfa_length] OF CHAR;
  68. {}  {   BYTE    = 0..255;    }
  69. {}      CHARNAME = (lletter, uletter, digit, blank, quote, atab,
  70.                       EndOfLine, FileMark, otherchar );
  71. {}      CHARINFO = RECORD
  72.                      name : charname;
  73.                      valu : CHAR
  74.                    END;
  75.         COUNTER = 1..Maxlines;
  76. {}      dfltstr = string (dflt_str_len) ;
  77.         FID     = string (fid_len) ;
  78.         lineindex = 1..Maxlinelen;
  79. {}      pageindex = BYTE;
  80.         Wordindex = 1..MaxWordlen;
  81.         Queuepointer = ^Queueitem;
  82.         Queueitem = RECORD
  83.                         linenumber : counter;
  84.                         NextInQueue: Queuepointer
  85.                     END;
  86.         EntryType = RECORD
  87.                         Wordvalue : alfa;
  88.                         FirstInQueue,
  89.                         lastinQueue: Queuepointer
  90.                      END;
  91.         treepointer = ^node;
  92.         node = RECORD
  93.                  entry : EntryType;
  94.                  left,
  95.                  right : treepointer
  96.                END;
  97.         SZ0     = string(1);
  98.         SZ255   = string(255);
  99. VAR
  100.   bell          : CHAR; 
  101.   blankindex    : BYTE;
  102.   currchar,                     { Current operative character }
  103.   nextchar      : charinfo;     { Look-ahead character }
  104.   fatal_error   : BOOLEAN;
  105.   FILE_ID,                      { CP/M file name }
  106.   PRN_ID,                       { basic file name + '.PRN' }
  107.   New_ID        :  string(14) ;  { basic file name + '.XRF' }
  108.   fbuffer     :STRING(255);     { Format buffer - before final Print }
  109.   FIN           : TEXT;
  110.   flushing      : (KNOT, DBL, STD, LIT);
  111.   form_feed     : CHAR;
  112.   Key           : ARRAY[1..NumKeysP1] OF alfa;
  113.   letters       : SET OF CHAR;
  114.   LISTING       : BOOLEAN;
  115.   Look          : char; { Character read in from File }
  116. {}{OUTPUT       : TEXT;  }      { Listing device -console or printer }
  117.   tab           : CHAR;
  118.   wordcount     : INTEGER;      { total # of words in file }
  119.   WordTree      : treepointer;
  120.   xeof,                 { EOF status AFTER a read }
  121.   xeoln         : BOOLEAN;      { EOLN status after a read }
  122.   GAP           : char      ;
  123. (*%C- [Control-C OFF]***********************************************)
  124. FUNCTION length(VAR x: STRING): INTEGER; 
  125. VAR
  126.     Y:   INTEGER;
  127.     Z:   CHAR;
  128. BEGIN
  129.    Z := X [0] ;
  130.    Y := ORD(Z) ;
  131.    LENGTH := Y ;
  132. END; {LENGTH}
  133. PROCEDURE koncat(VAR X: STRING; VAR Y: CHAR);
  134.  VAR LL :  INTEGER;
  135.  BEGIN
  136.    ll := ORD(X[0]);
  137.    ll := ll + 1 ;
  138.    X[ll} := Y ;
  139.  END; {KONCAT} 
  140. PROCEDURE setlength(VAR x: STRING; y: INTEGER);
  141. VAR
  142.     UL :  INTEGER; CY, CL : CHAR;
  143.  begin
  144.    UL := UPPER(X); CL := chr(ul);  cy := CHR(Y);
  145.    IF Y >  ul THEN X [0]  := CL;
  146.    ELSE X[0]  := CY ;
  147.  END; {SETLENGTH}
  148. FUNCTION index(VAR x: STRING; VAR y char): byte   ; EXTERNAL; 
  149. {  PROCEDURE PAGE(VAR fx: TEXT);
  150. BEGIN
  151.   WRITE(fx, form_feed);
  152. END;       }
  153. PROCEDURE CLEAR{output};
  154. VAR
  155.   ix : 1..24;
  156. BEGIN
  157.   FOR ix:=1 TO 24 DO WRITELN;
  158. END;
  159. PROCEDURE BuildTree(VAR tree: treepointer);
  160. VAR
  161.   CurrentWord : alfa;
  162.   Currentline: INTEGER;
  163.   FOUT: TEXT; { local output file }
  164.    PROCEDURE Entertree(VAR subtree: treepointer;
  165.                            Word   : alfa;
  166.                            line   :counter);
  167.    VAR
  168.      nextitem : Queuepointer;
  169.    BEGIN
  170.      IF subtree=nil THEN
  171.        BEGIN {create a new entry}
  172.          NEW(subtree);
  173.          WITH subtree^ DO BEGIN
  174.            left := nil;
  175.            right := nil;
  176.            WITH entry DO BEGIN
  177.              Wordvalue := Word;
  178.              NEW(FirstInQueue);
  179.              LastinQueue := FirstInQueue;
  180.              WITH FirstInQueue^ DO BEGIN
  181.                 linenumber := line;
  182.                 NextInQueue := nil;
  183.              END;{WITH FirstInQueue}
  184.            END;{WITH entry}
  185.          END;{WITH subtree}
  186.        END {create a new entry}
  187.      ELSE {append a list item}
  188.        WITH subtree^, entry DO
  189.          IF Word=Wordvalue THEN
  190.            BEGIN
  191.              IF lastinQueue^.linenumber <> line THEN
  192.                 BEGIN
  193.                   NEW(nextitem);
  194.                   WITH Nextitem^ DO BEGIN
  195.                     linenumber := line;
  196.                     NextInQueue := nil;
  197.                   END;{WITH}
  198.                   lastinQueue^.NextInQueue := Nextitem;
  199.                   lastinQueue := nextitem;
  200.                 END;
  201.            END
  202.          ELSE
  203.            IF Word < Wordvalue THEN
  204.              Entertree(left,Word,line)
  205.            ELSE
  206.              Entertree(right,Word,line);
  207.    END;{Entertree}
  208. Procedure ReadC({updating} VAR nextchar : charinfo;
  209.                 {returning}VAR currchar : charinfo );
  210. { revised 4 Jan 80, rep }
  211. { Defined the chars "^", "$", and "_" as lowercase letters }
  212. BEGIN   {+++ File status module. +++
  213.    Stores file status "AFTER" a read.
  214.    NOTE this play on words - after one char is
  215.    actually "PRIOR TO" the next character               }
  216.   xeof  := EOF(FIN);
  217.         {+++ read BYTE module +++}
  218.   IF NOT xeof THEN
  219.   xeoln := EOLN(FIN) ;
  220.   IF NOT xeof THEN
  221.         READ(FIN, Look);
  222.         {+++ current operative character module +++}
  223.   currchar := nextchar;
  224.         {+++ Classify the character just read +++}
  225.   WITH nextchar DO BEGIN{ Look-ahead character name module }
  226.     IF xeof THEN
  227.         name := FileMark
  228.     ELSE IF xeoln THEN
  229.         name := EndOfLine
  230.     ELSE IF Look IN ['^', '$', '_', 'a'..'z'] THEN {lower case plus}
  231.         name := lletter
  232.     ELSE IF Look IN ['A'..'Z'] THEN {upper case}
  233.         name := uletter
  234.     ELSE IF Look IN ['0'..'9'] THEN {digit}
  235.         name := digit
  236.     ELSE IF Look = '''' THEN
  237.         name := quote
  238.     ELSE IF Look = TAB THEN
  239.         name := atab
  240.     ELSE IF Look = space THEN
  241.         name := blank
  242.     ELSE
  243.         name := otherchar;
  244.     CASE name of{ store character value module }
  245.         EndOfLine,
  246.         FileMark:       Valu := space;
  247.         OTHERWISE       valu := look;
  248.     END{ case name of };
  249.   End{ Look-ahead character name module };
  250. END; {of ReadC}
  251. PROCEDURE GetL( VAR fbuffer :  string      );    
  252. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  253. {+      Get a line of text into users buffer.           +}
  254. {+      Flushes comment lines:                          +}
  255. {+      Flushes lines of Literals:  'this is it'        +}
  256. {+      Ignores special characters & tabs:              +}
  257. {+      Recognizes End of File and End of Line.         +}
  258. {+                                                      +}
  259. {+GLOBAL                                                +}
  260. {+      flushing : (KNOT, DBL, STD, LIT);               +}
  261. {+      fbuffer = dfltstr                               +}
  262. {+      LLmax   = 0..Max Line length;                   +}
  263. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  264. VAR
  265.   state : (scanning, terminal, overflow);
  266. BEGIN { GetL }
  267.    setlength(fbuffer,0);
  268.    fatal_error := FALSE;
  269.    state := scanning;
  270.   REPEAT
  271.     ReadC(nextchar, currchar);
  272. {}  WRITE(FOUT, currchar.valu);
  273. {}  IF listing THEN
  274.        WRITE( {OUTPUT,} currchar.valu);
  275.     IF (length(fbuffer) >= LLmax) THEN{ exceeded length of buffer }
  276.       BEGIN{ reset EOLN }
  277.         fatal_error := TRUE;
  278.         state := overflow;
  279.         setlength(fbuffer,0);
  280.         WRITE(bell);
  281.         WRITELN('EXCEEDED LENGTH OF INPUT BUFFER');
  282.       END
  283.     ELSE
  284.       BEGIN
  285.         IF (currchar.name IN [FileMark,EndOfLine]) THEN
  286.           state:=terminal{ END of line or END of file };
  287.         CASE flushing of
  288.             KNOT:
  289.                 CASE currchar.name of
  290.                 lletter, uletter, digit, blank:
  291.                         BEGIN{ store }
  292.                         KONCAT(FBUFFER,CURRCHAR.VALU) ; 
  293.                         END;
  294.                 atab, quote, otherchar:
  295.                         BEGIN{   Flush comments -convert
  296.                                  tabs & other chars to spaces }
  297.                         IF (currchar.valu='(') and (nextchar.valu='*')
  298.                           THEN flushing := DBL
  299.                         ELSE IF (currchar.valu='{') THEN 
  300.                            flushing := STD
  301.                         ELSE IF currchar.name=quote THEN
  302.                            flushing := LIT;
  303.                         { convert to a space }
  304.                             koncat(fbuffer,GAP);   
  305.                         END;
  306.                 otherwise    { END of line -or- file mark }
  307.                         KONCAT(fbuffer,currchar.valu)  
  308.                 END{ case currchar name of };
  309.             DBL:  { scanning for a closing  - double comment }
  310.                 IF (currchar.valu ='*') and (nextchar.valu =')')
  311.                   THEN flushing := KNOT;
  312.             STD:  { scanning for a closing curley  }
  313.                   IF currchar.valu = '}' THEN
  314.                       flushing := KNOT;
  315.             LIT:  { scanning for a closing quote }
  316.                   IF currchar.name = quote THEN
  317.                     flushing := KNOT
  318.         END{ flushing case }
  319.       END{ ELSE }
  320.   UNTIL (state<>scanning);
  321. END; {of GetL}
  322. PROCEDURE ReadWord;
  323. {++++++++++++++++++++++++++++++++++++++++++++++++}
  324. {+                                              +}
  325. {+       Analyze the Line into "words"          +}
  326. {+                                              +}
  327. {++++++++++++++++++++++++++++++++++++++++++++++++}
  328. LABEL   1;
  329. CONST
  330.   TOP = NumKeys + 1;
  331. VAR
  332.   ix,           {temp indexer}
  333.   idlen,        {length of the word}
  334.   Cpos : BYTE; { Current Position pointer }
  335. BEGIN{ ReadWord }
  336.   Cpos := 1; { start at the beginning of a line }
  337.   WHILE Cpos < length(fbuffer) DO
  338.     BEGIN {Cpos<length(fbuffer)}
  339.       WHILE (Cpos < length(fbuffer)) AND (fbuffer[Cpos]=space) DO
  340.         Cpos:=Cpos + 1;    {--- skip spaces ---}
  341.       idlen := 0;
  342.       WHILE (Cpos < length(fbuffer)) AND (fbuffer[Cpos ] <> space) DO
  343.         BEGIN{ accept only non-spaces }
  344.           IF idlen < MaxWordlen THEN
  345.             BEGIN
  346.               idlen := idlen + 1;
  347.               CurrentWord[idlen] := fbuffer[Cpos];
  348.             END;
  349.           Cpos := Cpos +1;
  350.         END{ WHILE };
  351. {}    IF idlen=0 THEN {no word was found} GOTO 1;
  352.       IF idlen >= blankindex THEN
  353.         blankindex := idlen
  354.       ELSE
  355.         REPEAT
  356.           CurrentWord[blankindex] := space;
  357.           blankindex := blankindex - 1;
  358.         UNTIL blankindex=idlen;
  359.       WordCount := WordCount + 1;
  360.       {++++++++++++++++++++++++++++++++++}
  361.       {+   linear search with sentinel  +}
  362.       {++++++++++++++++++++++++++++++++++}
  363.           Key[TOP] := CurrentWord;
  364.           ix := 0;
  365.           REPEAT
  366.             ix := ix + 1;
  367.           UNTIL Key[ix] = CurrentWord;
  368.       {++++++++++++++++++++++++++++++++++}
  369. {}    IF ix=TOP THEN {CurrentWord is not a reserve word, so}
  370.          EnterTree(tree,CurrentWord,Currentline);
  371.       1:{Here is no word <length of word=0>};
  372.     END; {WHILE Cpos<length(fbuffer)}
  373. END; {of Readword}
  374. BEGIN{BuildTree}
  375. {}ASSIGN(FOUT,PRN_ID); REWRITE(FOUT);
  376.   PAGE(FOUT);
  377.   Currentline := 0;
  378.   nextchar.name := blank;       { Initialize next char to a space }
  379.   nextchar.valu := space;
  380.   ReadC({update}    nextchar,   { Initialize current char to space }
  381.         {returning} currchar);  { First char from file in nextchar }
  382.   WHILE ((currchar.name<>filemark) AND (NOT fatal_error)) DO
  383.     BEGIN
  384.       Currentline := Currentline + 1;
  385.       WRITE(FOUT, Currentline:6,': ');
  386.       IF listing THEN WRITE({OUTPUT,} Currentline:6,': ');
  387.       GetL(fbuffer) { attempt to read the first line };
  388.       WRITELN(FOUT);
  389.       IF listing THEN WRITELN{output};
  390.       ReadWord; {Analyze the Text into single 'words' }
  391.     END; {While}
  392.   PAGE(FOUT);
  393.    CLOSE(FOUT) ;
  394. END; {of BuildTree}{CLOSE(PRN_ID);}
  395. PROCEDURE PrintTree(tree: treepointer);
  396. {
  397. GLOBAL
  398.         MaxOnLine   = max line references per line
  399.         NumberWidth = field for each number
  400. }
  401. VAR
  402.   XOUT: TEXT; { local output file }
  403.   pageposition: pageindex;
  404.    PROCEDURE PrintEntry(subtree: treepointer;
  405.                         VAR position: pageindex);
  406.    VAR  ix: Wordindex;
  407.         itemcount : 0..Maxlinelen;
  408.         itemptr : Queuepointer;
  409.         PROCEDURE PrintLine(VAR Currentposition: pageindex;
  410.                                 newlines: pageindex);
  411.         VAR
  412.           linecounter: pageindex;
  413.         BEGIN
  414. {}        IF (Currentposition + newlines) < MaxOnPage THEN
  415.             BEGIN
  416. {}              FOR linecounter:=1 TO newlines DO WRITELN(XOUT);
  417. {}              IF listing THEN
  418.                   FOR linecounter:=1 TO newlines DO WRITELN{OUTPUT};
  419.                 Currentposition := Currentposition + newlines;
  420.             END
  421.           ELSE
  422.             BEGIN
  423. {}            PAGE(XOUT);
  424. {}            WRITELN(XOUT,heading);
  425. {}            FOR linecounter := 1 TO headingsize - 1 DO
  426.                  WRITELN(XOUT);
  427. {}            IF listing THEN
  428.                 BEGIN
  429.                   CLEAR{OUTPUT}; {PAGE(OUTPUT);}
  430.                   WRITELN({OUTPUT,} heading);
  431.                   FOR linecounter := 1 TO headingsize - 1 DO
  432.                      WRITELN{OUTPUT};
  433.                 END;
  434.               Currentposition := headingsize + 1;
  435.             END
  436.         END;{PrintLine}
  437.    BEGIN{PrintEntry}
  438.      IF subtree<>nil THEN
  439.         WITH subtree^ DO BEGIN
  440.           PrintEntry(left,position);
  441.           PrintLine(position,entrygap + 1);
  442.           WITH entry DO BEGIN
  443. {}          FOR ix:=1 TO MaxWordlen DO
  444.               WRITE(XOUT, WordValue[ix]);
  445. {}          IF listing THEN
  446.                FOR ix:=1 TO MaxWordlen DO
  447.                   WRITE({OUTPUT,} WordValue[ix]);
  448.             itemcount := 0;
  449.             itemptr := FirstInQueue;
  450.             WHILE itemptr <> nil DO
  451.               BEGIN
  452.                 itemcount := itemcount + 1;
  453.                 IF itemcount > MaxOnLine THEN
  454.                   BEGIN
  455.                     PrintLine(position,1);
  456. {}                  WRITE(XOUT, space:MaxWordlen);
  457. {}                  IF listing THEN 
  458.                        WRITE({OUTPUT,} space:MaxWordlen);
  459.                     itemcount := 1;
  460.                   END;
  461. {}              WRITE(XOUT, itemptr^.linenumber: numberwidth);
  462. {}              IF listing THEN
  463.                    WRITE({OUTPUT,}itemptr^.linenumber: numberwidth);
  464.                 itemptr := itemptr^.NextInQueue;
  465.               END;{WHILE}
  466.           END; {WITH entry}
  467.           PrintEntry(right,position);
  468.         END; {WITH subtree^}
  469.    END; {PrintEntry}
  470. BEGIN{PrintTree}
  471.   READFN(input,xout);
  472.   Rewrite(Xout) ;  
  473.   PAGE(XOUT);
  474.   PagePosition := MaxOnPage;
  475.   PrintEntry(tree,PagePosition);
  476.   PAGE(XOUT);
  477. END; {of PrintTree}{CLOSE(New_ID);}
  478. (*%C+ [Control-C ON]*******************************)
  479. FUNCTION ConnectFiles: boolean;
  480. TYPE
  481.   Linebuffer = string(80);
  482. VAR
  483.   ix,jx,
  484.   Cmllen  : BYTE;
  485.   Cmlline : LINEBUFFER ;
  486. BEGIN{ ConnectFiles }
  487.   fatal_error := FALSE;
  488.   ConnectFiles := TRUE;
  489.    WRITELN('Enter Complete Filenames ') ;
  490.    WRITELN ;
  491.    WRITELN('Input File:');
  492.    READLN(FILE_ID);
  493.    WRITELN('Cross-Reference output:'); 
  494.    READLN(NEW_ID); 
  495.    WRITELN('Printed output:');
  496.    READLN(PRN_ID);
  497.    WRITELN;
  498.    ASSIGN(FIN,FILE_ID);
  499.    RESET(FIN);
  500.    IF EOF(FIN) THEN 
  501.       BEGIN
  502.         WRITE(BELL);
  503.         WRITELN('FILE  NOT  FOUND !!!!!!');
  504.         fatal_error := TRUE;
  505.         ConnectFiles := FALSE;
  506.       END
  507.    ELSE 
  508.      writeln(FILE_ID,PRN_ID,NEW_ID); 
  509. END{ of ConnectFiles };
  510. (*%C- [control-c OFF]***********************************)
  511. PROCEDURE Initialize;
  512. VAR
  513.   Ch: CHAR;
  514.   con_wanted,
  515.   tty_wanted : BOOLEAN;
  516. BEGIN
  517.   bell := CHR(7); GAP := ' ' ;
  518.   IF ConnectFiles THEN
  519.     BEGIN
  520.       letters := ['A'..'Z','a'..'z'];
  521.         Key[ 1] := 'AND     ';
  522.         Key[ 2] := 'ARRAY   ';
  523.         Key[ 3] := 'BEGIN   ';
  524.         Key[ 4] := 'BOOLEAN '; {+++ NOT A RESERVE WORD +++}
  525.         Key[ 5] := 'CASE    ';
  526.         Key[ 6] := 'CHAR    '; {+++ NOT A RESERVE WORD +++}
  527.         Key[ 7] := 'CONST   ';
  528.         Key[ 8] := 'DIV     ';
  529.         Key[ 9] := 'DOWNTO  ';
  530.         Key[10] := 'DO      ';
  531.         Key[11] := 'ELSE    ';
  532.         Key[12] := 'END     ';
  533.         Key[13] := 'EXIT    ';  {+++ NOT a Pascal reserve word +++}
  534.         Key[14] := 'FILE    ';
  535.         Key[15] := 'FOR     ';
  536.         Key[16] := 'FUNCTION';
  537.         Key[17] := 'GOTO    ';
  538.         Key[18] := 'IF      ';
  539.         Key[19] := 'IN      ';
  540.         Key[20] := 'INPUT   '; {+++ NOT A RESERVE WORD +++}
  541.         Key[21] := 'INTEGER '; {+++ NOT A RESERVE WORD +++}
  542.         Key[22] := 'LABEL   ';
  543.         Key[23] := 'MOD     ';
  544.         Key[24] := 'NIL     ';
  545.         Key[25] := 'NOT     ';
  546.         Key[26] := 'OF      ';
  547.         Key[27] := 'OR      ';
  548.         Key[28] := 'OUTPUT  '; {+++ NOT A RESERVE WORD +++}
  549.         Key[29] := 'PACKED  ';
  550.         Key[30] := 'PROCEDUR';
  551.         Key[31] := 'PROGRAM ';
  552.         Key[32] := 'REAL    '; {+++ NOT A RESERVE WORD +++}
  553.         Key[33] := 'RECORD  ';
  554.         Key[34] := 'REPEAT  ';
  555.         Key[35] := 'SET     ';
  556.         Key[36] := 'STRING  ';  {+++ NOT a Pascal reserve word +++}
  557.         Key[37] := 'TEXT    '; {+++ NOT A RESERVE WORD +++}
  558.         Key[38] := 'THEN    ';
  559.         Key[39] := 'TO      ';
  560.         Key[40] := 'TYPE    ';
  561.         Key[41] := 'UNTIL   ';
  562.         Key[42] := 'VAR     ';
  563.         Key[43] := 'WHILE   ';
  564.         Key[44] := 'WITH    ';
  565.         Key[45] := 'WRITE   '; {+++ NOT A RESERVE WORD +++}
  566.         Key[46] := 'WRITELN '; {+++ NOT A RESERVE WORD +++}
  567.         blankindex := alfa_length;
  568.         tab     := CHR(9);  { ASCII Tab character }
  569.         form_feed := CHR(12);  gap  := CHR(32);
  570.         flushing := KNOT{ flushing };
  571.         WRITELN;
  572.         WRITELN('Output Device:');
  573.         WRITE(  '  CONSOLE ->');
  574.         READLN(Ch);
  575.         con_wanted := ( (Ch='Y') OR (Ch='y') );
  576.         WRITE(  '  PRINTER ->');
  577.         READLN(Ch);
  578.         tty_wanted := ( (Ch='Y') OR (Ch='y') );
  579.         If tty_wanted THEN
  580.            con_wanted := FALSE;
  581.         IF NOT (con_wanted OR tty_wanted) THEN
  582.           LISTING := FALSE
  583.         ELSE
  584.           BEGIN
  585.             LISTING := TRUE;
  586. {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  587.             IF con_wanted THEN REWRITE('CON:', OUTPUT);
  588.             IF tty_wanted THEN REWRITE('LST:', OUTPUT);
  589. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  590.           END;
  591.         WRITELN;
  592.     END; {IF ConnectFiles}
  593. END; {of Initialize}
  594. BEGIN { Cross Reference }
  595.   CLEAR{output};
  596.   WRITELN(' ':22, 'CROSS REFERENCE GENERATOR');
  597.   WRITELN;WRITELN;WRITELN;WRITELN;
  598.   Initialize;
  599.   IF NOT fatal_error THEN
  600.     BEGIN
  601.       WordTree := NIL;          {Make the Tree empty}
  602.       writeln('Pass 1 [Listing] Begins ...');BuildTree(WordTree); 
  603.       writeln('Pass 2 [Cross-Ref] Begins ...');PrintTree(WordTree); 
  604.     END;
  605. {}WRITELN;
  606. END. { Cross Reference }
  607.