home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
TURBOPAS
/
CROSSREF.ARK
/
CR-M01.INC
< prev
next >
Wrap
Text File
|
1987-04-18
|
10KB
|
230 lines
{.pa}
{**************************** procedure BuildTree ***************************}
procedure BuildTree(var Tree :TreePointer;
Key :IdentType;
LengthWord,
LNumber :Index;
var Status :Info );
{ This driver procedure will determine if a word is a reserved word by running
a BinarySearch. If not reserved, then it will be inserted into the tree by
running InsertTree. During insertion, if the word is new to the tree it
will be put on to a node, otherwise it will run EnQueue to put the line
number into a queue. The variables Reserved, Key, LengthWord, LNumber, &
Status are used as globals within this procedure. }
var
TestKey :RWord; { test key for binary search. }
UpKey :IdentType; { upper case version of identifier. }
J :Index; { loop index. }
Found :boolean; { has a reserved word been found. }
{************************* function BinarySearch *************************}
function BinarySearch (TestKey :RWord):boolean;
{ This function will check if a word is a reserved or a semi-reserved word.
A true boolean flag (BinarySearch) will be returned if there is an
occurance, otherwise false. }
var
Found :boolean; { found match }
Mid, { median of list }
Low, { lower bound of list }
High :Index; { upper bound of list }
begin
Low := 1; { set lower bound }
High := MaxReservedWords; { set upper bound }
Found := false;
while (Low <= High) and (not Found) do { binary search loop }
begin
Mid := (Low + High) div 2;
if TestKey = Reserved[Mid] then
begin
Found := true;
Status.UsedReserved[Mid] := Status.UsedReserved[Mid] + 1;
end
else
if TestKey < Reserved[Mid] then
High := Mid - 1
else
Low := Mid + 1
end; { while }
BinarySearch := Found { return result of search }
end; { function BinarySearch }
{**************************** procedure EnQueue ***************************}
procedure EnQueue(var Entry :EntryType);
{ This procedure will add a line number to the queue. }
var
NewPointer :QueuePointer; { new node of queue }
begin
new(NewPointer); { allocate space in queue }
NewPointer^.LineNumber := LNumber;
NewPointer^.Next := nil;
if Entry.Head = nil then
begin { queue is empty }
Entry.Head := NewPointer;
Entry.Tail := NewPointer
end
else
begin { store line number in }
Entry.Tail^.Next := NewPointer; { queue }
Entry.Tail := NewPointer
end
end; { procedure EnQueue }
{************************** procedure InsertTree **************************}
procedure InsertTree (var Tree :TreePointer);
{ This procedure will insert an identifier into the tree. If the
identifier already exists, then the its line number will be enqueued. }
begin
if Tree = nil then
begin
new(Tree); { start new node of tree }
with Tree^ do
begin
Status.DifferentIdents := Status.DifferentIdents + 1;
Left := nil; { initialize sub-node }
Right := nil; { initialize sub-node }
Entry.Ident := Key; { unchanged identifier }
Entry.UpIdent := UpKey; { upper case Ident }
Entry.Head := nil; { initialize queue head }
Entry.Tail := nil; { initialize queue tail }
EnQueue (Entry);
end;
end { if Tree = nil }
else
with Tree^ do
if UpKey < Entry.UpIdent then
InsertTree (Left) { go to left node of tree }
else
if UpKey > Entry.UpIdent then
InsertTree (Right) { go to right node of tree }
else
EnQueue (Entry) { duplicate Key }
end; { procedure InsertTree }
{****************************** procedure EnterTree **************************}
begin
for J := 1 to MaxIdentLength do { convert to upper case }
UpKey[J] := upcase(Key[J]);
if LengthWord <= MaxReservedLength then { word can't be reserved if it }
{ is longer than max. reserved }
begin
for J := 1 to MaxReservedLength do
TestKey[J] := UpKey[J];
Found:=BinarySearch (TestKey); { determine if reserved }
end
else
Found := false;
if not Found then
begin
Status.TotalIdents := Status.TotalIdents + 1; { total idents }
InsertTree (Tree) { insert ident into tree }
end
else
Status.TotalReserved := Status.TotalReserved + 1
end; { procedure EnterTree }
{.pa}
{************************* procedure FindWord *******************************}
procedure FindWord( LText :LineType;
Number :Index;
var State :Condition;
var Tree :TreePointer;
var Status :Info );
{ This procedure will pick out words from a line of text. Only words
containing alphabet, numbers or underscore characters will be taken; then
call a function SearchLine to see if it already occurs on the current line.}
var
I,J,K :Index; { array index's. }
Word :IdentType; { word built by program. }
Ch :char; { character of LINETEXT. }
Comment, { the start of a comment? }
FoundWord :boolean; { has a word been created? }
Line :WordType; { line of input file. }
begin
for K := 1 to MaxIdentLength do
Word[K] := ' '; { init. WORD array to blanks }
J := 1; { index of WORD array. }
I := 0; { index of LINE array. }
FoundWord := false;
Line := LText.Line; { line of input file. }
while I < LText.Len do { scan through line of text }
begin
I := I + 1; { increment index of LINE array }
Ch := Line[I]; { assign one char }
if (State = CCopy) and (J = 1) and (Ch in Alpha) then { char is valid }
begin
Word[1] := Ch;
K := I; { start index of word }
I := I + 1;
while (I <= LText.Len) and { build word to MaxIdentLength }
(Line[I] in AlphaNumeric) and
(J < MaxIdentLength) do
begin
J := J + 1;
Word[J] := Line[I];
I := I + 1;
end;
while (I < LText.Len) and { get rid of excess word }
(Line[I] in AlphaNumeric) do
I := I + 1;
Status.AvgIdentLength := Status.AvgIdentLength + (I-K);
FoundWord := true; { word has been found }
BuildTree(Tree,Word,J,Number,Status);
for K := 1 to J do
Word[K] := ' ';
J := 1 { start next word. }
end { if -- then }
else
begin
Comment := (Ch = '{') or ((Ch = '(') and (Line[I+1] = '*'));
if (State = SkipComment) or Comment then
begin
if Comment then
begin
Status.Comments := Status.Comments + 1;
State := SkipComment;
end;
while (State = SkipComment) and { get rid of comments }
(I < LText.Len) do
begin
I := I + 1;
if Line[I] = '}' then
State := CCopy;
if I+1 <= LText.Len then
if (Line[I] = '*') and (Line[I+1] = ')') then
State := CCopy;
end; { while }
end;
if (State = SkipString) or
(Ch = '''') then
repeat { get rid of strings }
I := I + 1;
if Line[I] = '''' then
State := CCopy
else
State := SkipString
until (State = CCopy) or (I = LText.Len)
end; { else }
end; { while }
if not FoundWord then
Status.CommentLines := Status.CommentLines + 1 { count comment lines }
end; { procedure FindWord }