jduarte@siam.ICS.UCI.EDU (Jose_Duarte) (08/09/90)
Hello Folks,
I am currently writing a routine in Ada under Berkeley Unix 4.2
using the Verdix ADA compiler 6.0. I am using the standard Text_IO
routines GET and PUT to implement a function to save a tree in text
format. I save the tree using a depth-first algorithm, and this means
that I have to call the Save_Tree function recursively...I am using a
Sun 4 machine to work on, and I get a BUS ERROR once in a while...No
exceptions are raised...just a BUS ERROR...It doesn't happen always,
and my routine doesn't "bite the dust" in the same place when I do
get a BUS ERROR...My question is: Has anyone else had the same problem ?
I know this is too general a question, but I just thought I'd ask...
Jose Duarte.
------------------------------------------------------
CODE:
with Lines,
Text_IO,
Tree_Generation,
File_Manager,
Command_Line,
CTA_System,
Tables;
package body Tree_Traversal is
------------------------------------------------------
-- procedure Print_Tree_2
--
-- This procedure Prints out the Classification Tree
-- using a depth-first recursive algorithm. The User's
-- Manual displays a Tree and a sample tree ouput. If
-- The Indentation_Level is too long, then the output
-- will be messed up. Tough Luck !!!
--
-- There are three cases possible when Printing the tree:
--
-- 1. The Node_Ptr parameter is null.
-- The words "null node" are ouput
--
-- 2. The Node_Ptr parameter points to a terminal node:
-- The Node classification is determined from the
-- node record field "Classification", and then the
-- symbols <+> or <-> or <*> are output.
--
-- 3. The Node_Ptr points to a NONTERMINAL record node:
-- The Metric Name is extracted from the Metrics
-- Table according to the "Metric_Code" field in the
-- record. Next, the Arc_List pointer is initialized
-- to point to the first arc. A "while" loop calls
-- the Print_Tree procedure recursively for each arc
-- in the arcs_list with a new Indentation_Level.
--
------------------------------------------------------
procedure Print_Tree_2(F : Text_IO.File_Type;
Node_Ptr : Tree_Generation.Tree_Node_Pointer;
Indentation_Level: Natural ) is
use File_Manager,CTA_System,Tree_Generation,Text_IO;
Arc_List : Tree_Arc_Pointer;
Metric_Type: Tables.Value_Type;
Metric_Code: POSITIVE;
Temp_Str : Lines.Normal_Line;
Int1,Int2 : INTEGER;
F1,F2 : FLOAT;
begin
New_Line(F);
-- indent the proper number of columns:
For X in NATURAL range 1..Indentation_Level loop
Put(F,'|');
end loop;
-- case 1: The pointer is a null pointer
if (Node_Ptr = null) then
Put(F,"<null node>");
return;
end if;
-- case 2: The pointer points to a terminal node
if (Is_Terminal(Node_Ptr)) then
case Return_Classification(Node_Ptr) is
when CTA_System.P => Put(F,"<+>");
when CTA_System.N => Put(F,"<->");
when CTA_System.Z => Put(F,"<Z>");
when CTA_System.M => Put(F,"<M>");
when CTA_System.D => Put(F,"<D>");
when CTA_System.U => Put(F,"<U>");
end case;
-- New_Line(F);
return;
end if;
-- case 3: a NONTERMINAL
-- it's not null and not a terminal
-- i.e. it's a nonterminal:
-- put out Metric Name - a conversion is required:
Put(F,Lines.IMAGE(Get_Metric_Name(Return_Metric_Code(Node_Ptr))));
-- New_Line(F);
-- start off with the first child node:
Arc_List := Get_Arc_List_Pointer(Node_Ptr);
Metric_Type := Get_Metric_Type(Return_Metric_Code(Node_Ptr));
while (Arc_List /= null) loop
Get_Range_Values(Arc_List,Temp_Str,Int1,Int2,F1,F2);
if NOT (Is_Terminal(Get_Child_Node_From_Arc(Arc_List))) then
New_Line(F);
For X in NATURAL range 1..Indentation_Level+4 loop
Put(F,' ');
end loop;
case Metric_Type is
when Tables.CHAR =>
Put(F," ( " & Lines.IMAGE(Temp_Str) & " ) ");
when Tables.INT =>
Put(F, " ( ");
Put(F, INTEGER'IMAGE(Int1));
Put(F," , ");
Put(F, INTEGER'IMAGE(Int2));
Put(F, " ) ");
when Tables.REAL =>
Put(F, " ( ");
CTA_System.CTA_Floats.Put(F,F1,1,3,3);
Put(F," , ");
CTA_System.CTA_Floats.Put(F, F2,1,3,3);
Put(F, " ) ");
end case;
end if;
Print_Tree_2(F,Get_Child_Node_From_Arc(Arc_List), Indentation_Level+5);
if (Is_Terminal(Get_Child_Node_From_Arc(Arc_List))) then
case Metric_Type is
when Tables.CHAR =>
Put(F," ( " & Lines.IMAGE(Temp_Str) & " ) ");
when Tables.INT =>
Put(F, " ( ");
Put(F, INTEGER'IMAGE(Int1));
Put(F," , ");
Put(F, INTEGER'IMAGE(Int2));
Put(F, " ) ");
when Tables.REAL =>
Put(F, " ( ");
CTA_System.CTA_Floats.Put(F,F1,1,3,3);
Put(F," , ");
CTA_System.CTA_Floats.Put(F, F2,1,3,3);
Put(F, " ) ");
end case;
-- New_Line(F);
end if;
Arc_List := Next_Arc(Arc_List);
end loop;
end Print_Tree_2;
------------------------------------------------------
procedure Print_Tree(Node_Ptr : Tree_Generation.Tree_Node_Pointer;
Indentation_Level: Natural := 0) is
use Text_IO;
F: File_Type;
begin
-- Get the output filename from the command-line:
Lines.Assign(CTA_System.Filename,Command_Line.argv(2).s);
CREATE(F,Out_File,Lines.IMAGE(CTA_System.Filename));
-- Save the tree to a file:
Print_Tree_2(F,Node_Ptr,Indentation_Level);
CLOSE(F);
end;
end Tree_Traversal;