{**************************************************************************** PROGRAM : Cross Reference VERSION : 4 MODIFIED : 1/31/87 AUTHOR : Milton Hom DESCRIPTION: This a program will produce a cross-reference table of identifiers from a Pascal program. Each identifier will have a list of line numbers indicating its location throughout the program. Also, all identifiers, different identifier, code lines, comment lines, & blank lines will be counted. The most & least used identifier will be counted. INPUT: An ASCII file in Pascal. Include file(s) are not recognized by this program. Therefore, each file(s) must be cross referenced separately. OUTPUT: A table with all identifiers sorted from A to Z along with all line numbers associated with it and statistics of the program. This table will be sent to an output file specified by the user. *****************************************************************************} {.pa} program CrossReference(input,output); {$A-} { compiler directive for recursion (default: A+) } const MaxIdentLength = 15; { max. length of identifier } MaxLengthOfLine = 96; { max. length of line in input file } MaxReservedWords = 40; { max. no.# of reserved & semi-reserved words } { do not change following constants. } MaxReservedLength = 9; { max. length of reserved word } type Index = -1..10000; { subrange for array index } IdentType = array[1..MaxIdentLength] of char; { ident type } WordType = array[1..MaxLengthOfLine] of char; { max. size of word type } RWord = array[1..MaxReservedLength] of char; { max. size of reserved } QueuePointer = ^QueueItem; QueueItem = record LineNumber :Index; { line number of ident } Next :QueuePointer; end; EntryType = record UpIdent, { Upper case ident } Ident :IdentType; { Identifier } Head, { queue Head } Tail :QueuePointer; { queue Tail } end; TreePointer = ^TreeType; TreeType = record Entry :EntryType; Left, { pointer to left node } Right :TreePointer; { pointer to right node } end; LineType = { record of line info } record Line :WordType; { line of input file } Len :0..MaxLengthOfLine; { length of line } end; Info = record TotalLines, { total number of lines } CommentLines, { total number of comment lines } BlankLines, { total number of blank lines } Comments, { total number of comments } TotalIdents, { total number of identifiers } DifferentIdents, { total number of different identifiers } TotalReserved, { total number of reserved words } MostUsedNumber, { number of identifier used the most } LeastUsedNumber: Index; { number of identifier used the least } AvgIdentLength: real; { average length of identifier } MostUsedIdent, { identifier used the most } LeastUsedIdent: IdentType; { identifier used the least } UsedReserved: { number of each reserved word used } array[1..MaxReservedWords] of Index; end; ReservedType = array[1..MaxReservedWords] of RWord; NameType = string[14]; Condition = (CCopy,SkipComment,SkipString); SetType = set of char; {.pa} var Tree: TreePointer; { binary tree of idents, line no & lower case idents } Reserved: ReservedType; { reserved & semi-reserved words } LineText: LineType; { one line of text from input file } Status: Info; { information on cross-referenced table } State: Condition; { diff. states for building words } SourceName, { name of source file } TableName: NameType; { name of table } InFile, { source file var of input } TableFile: text; { output file var of Table } Stop: boolean; { don't cross-reference a program } Number: Index; { total line numbers in input file } Alpha, { alphabet } AlphaNumeric, { alphabet & number } EndWord: SetType; { char. showing end of word } {$I cr-m01.inc} { BuildTree, BinarySearch, InsertTree, EnQueue & FindWord } {$I cr-m02.inc} { ReadLine, ClearLine, ReadInReserved, & DisplayStatus } {$I cr-m03.inc} { PrintTree } {$I cr-m04.inc} { Compare, OpenFile, AnotherCross, InitializeTree, } { InitializeStatus & Title } {.pa} {****************************** main program *********************************} begin Alpha := ['A'..'Z' , 'a'..'z']; AlphaNumeric := ['A'..'Z' , 'a'..'z' , '0'..'9' , '_']; EndWord := ['^' , '*' , '(' , ')' , '-' , '+' , '=' , '[' , ']' , ';', ':' , '''', '"' , ',' , '.' , '/' , '<' , '>' , ' ' , '{', '}' ]; ReadInReserved (Reserved); { read in reserved words } repeat Titles; { display titles } Stop := false; State := CCopy; { set state of building words } Number := 0; OpenFile (InFile,TableFile,Stop, { open source file & output } SourceName,TableName); if not Stop then begin gotoxy(1,13); write('Scanning ',SourceName,' on line '); InitializeStatus (Status); { initialize status } InitializeTree (Tree); { initialize tree } while not eof(InFile) do { find identifier loop } begin ClearLine (LineText); { blank out line buffer } ReadLine (InFile,LineText); { take 1 line from input file } Number := Number + 1; { count lines of input file } gotoxy(19+length(SourceName),13); { display line number } write(Number); if LineText.Len = 0 then { if blank line then skip it } with Status do BlankLines := BlankLines + 1 { count blank lines } else FindWord (LineText,Number, { get words from line of text } State,Tree,Status); end; { while } Status.TotalLines := Number; { total lines in ref program } PrintTree (Tree,TableFile,Status, { write a table of identifiers } SourceName,TableName ); { with line numbers to disk } close(InFile) end; { if not Stop } until not AnotherCross; { prompt user with question } end.