|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: B T
Length: 34098 (0x8532)
Types: TextFile
Names: »B«
└─⟦a7d1ea751⟧ Bits:30000550 8mm tape, Rational 1000, !users!projects 94_04_11
└─⟦129cab021⟧ »DATA«
└─⟦this⟧
└─⟦2f6cfab89⟧ Bits:30000547 8mm tape, Rational 1000, !projects 94-01-04
└─⟦d65440be7⟧ »DATA«
└─⟦this⟧
with Dfa, Int_Io, Misc_Defs, Text_Io, Misc, Tblcmp, Ccl, External_File_Manager;
with Ecs, Nfa, Tstring, Gen, Skeleton_Manager;
use Misc_Defs, External_File_Manager;
package body Dfa is
use Tstring;
-- check_for_backtracking - check a DFA state for backtracking
--
-- ds is the number of the state to check and state[) is its out-transitions,
-- indexed by equivalence class, and state_rules[) is the set of rules
-- associated with this state
Did_Stk_Init : Boolean := False;
Stk : Int_Ptr;
procedure Check_For_Backtracking (Ds : in Integer;
State : in Unbounded_Int_Array) is
use Misc_Defs;
begin
if (Dfaacc (Ds).Dfaacc_State = 0) then
-- state is non-accepting
Num_Backtracking := Num_Backtracking + 1;
if (Backtrack_Report) then
Text_Io.Put (Backtrack_File, "State #");
Int_Io.Put (Backtrack_File, Ds, 1);
Text_Io.Put (Backtrack_File, "is non-accepting -");
Text_Io.New_Line (Backtrack_File);
-- identify the state
Dump_Associated_Rules (Backtrack_File, Ds);
-- now identify it further using the out- and jam-transitions
Dump_Transitions (Backtrack_File, State);
Text_Io.New_Line (Backtrack_File);
end if;
end if;
end Check_For_Backtracking;
-- check_trailing_context - check to see if NFA state set constitutes
-- "dangerous" trailing context
--
-- NOTES
-- Trailing context is "dangerous" if both the head and the trailing
-- part are of variable size \and/ there's a DFA state which contains
-- both an accepting state for the head part of the rule and NFA states
-- which occur after the beginning of the trailing context.
-- When such a rule is matched, it's impossible to tell if having been
-- in the DFA state indicates the beginning of the trailing context
-- or further-along scanning of the pattern. In these cases, a warning
-- message is issued.
--
-- nfa_states[1 .. num_states) is the list of NFA states in the DFA.
-- accset[1 .. nacc) is the list of accepting numbers for the DFA state.
procedure Check_Trailing_Context (Nfa_States : in Int_Ptr;
Num_States : in Integer;
Accset : in Int_Ptr;
Nacc : in Integer) is
Ns, Ar : Integer;
State_Var, Type_Var : State_Enum;
use Misc_Defs, Misc, Text_Io;
begin
for I in 1 .. Num_States loop
Ns := Nfa_States (I);
Type_Var := State_Type (Ns);
Ar := Assoc_Rule (Ns);
if ((Type_Var = State_Normal) or
(Rule_Type (Ar) /= Rule_Variable)) then
null;
-- do nothing
else
if (Type_Var = State_Trailing_Context) then
-- potential trouble. Scan set of accepting numbers for
-- the one marking the end of the "head". We assume that
-- this looping will be fairly cheap since it's rare that
-- an accepting number set is large.
for J in 1 .. Nacc loop
if (Check_Yy_Trailing_Head_Mask (Accset (J)) /= 0) then
Text_Io.Put
(Standard_Error,
"aflex: Dangerous trailing context in rule at line ");
Int_Io.Put (Standard_Error, Rule_Linenum (Ar), 1);
Text_Io.New_Line (Standard_Error);
return;
end if;
end loop;
end if;
end if;
end loop;
end Check_Trailing_Context;
-- dump_associated_rules - list the rules associated with a DFA state
--
-- goes through the set of NFA states associated with the DFA and
-- extracts the first MAX_ASSOC_RULES unique rules, sorts them,
-- and writes a report to the given file
procedure Dump_Associated_Rules (F : in File_Type; Ds : in Integer) is
J : Integer;
Num_Associated_Rules : Integer := 0;
Rule_Set : Int_Ptr;
Size, Rule_Num : Integer;
begin
Rule_Set := new Unbounded_Int_Array (0 .. Max_Assoc_Rules + 1);
Size := Dfasiz (Ds);
for I in 1 .. Size loop
Rule_Num := Rule_Linenum (Assoc_Rule (Dss (Ds) (I)));
J := 1;
while (J <= Num_Associated_Rules) loop
if (Rule_Num = Rule_Set (J)) then
exit;
end if;
J := J + 1;
end loop;
if (J > Num_Associated_Rules) then
--new rule
if (Num_Associated_Rules < Max_Assoc_Rules) then
Num_Associated_Rules := Num_Associated_Rules + 1;
Rule_Set (Num_Associated_Rules) := Rule_Num;
end if;
end if;
end loop;
Misc.Bubble (Rule_Set, Num_Associated_Rules);
Text_Io.Put (F, " associated rules:");
for I in 1 .. Num_Associated_Rules loop
if (I mod 8 = 1) then
Text_Io.New_Line (F);
end if;
Text_Io.Put (F, Ascii.Ht);
Int_Io.Put (F, Rule_Set (I), 1);
end loop;
Text_Io.New_Line (F);
exception
when Storage_Error =>
Misc.Aflexfatal
("dynamic memory failure in dump_associated_rules()");
end Dump_Associated_Rules;
-- dump_transitions - list the transitions associated with a DFA state
--
-- goes through the set of out-transitions and lists them in human-readable
-- form (i.e., not as equivalence classes); also lists jam transitions
-- (i.e., all those which are not out-transitions, plus EOF). The dump
-- is done to the given file.
procedure Dump_Transitions (F : in File_Type;
State : in Unbounded_Int_Array) is
Ec : Integer;
Out_Char_Set : C_Size_Bool_Array;
begin
for I in 1 .. Csize loop
Ec := Ecgroup (I);
if (Ec < 0) then
Ec := -Ec;
end if;
Out_Char_Set (I) := (State (Ec) /= 0);
end loop;
Text_Io.Put (F, " out-transitions: ");
Ccl.List_Character_Set (F, Out_Char_Set);
-- now invert the members of the set to get the jam transitions
for I in 1 .. Csize loop
Out_Char_Set (I) := not Out_Char_Set (I);
end loop;
Text_Io.New_Line (F);
Text_Io.Put (F, "jam-transitions: EOF ");
Ccl.List_Character_Set (F, Out_Char_Set);
Text_Io.New_Line (F);
end Dump_Transitions;
-- epsclosure - construct the epsilon closure of a set of ndfa states
--
-- NOTES
-- the epsilon closure is the set of all states reachable by an arbitrary
-- number of epsilon transitions which themselves do not have epsilon
-- transitions going out, unioned with the set of states which have non-null
-- accepting numbers. t is an array of size numstates of nfa state numbers.
-- Upon return, t holds the epsilon closure and numstates is updated. accset
-- holds a list of the accepting numbers, and the size of accset is given
-- by nacc. t may be subjected to reallocation if it is not large enough
-- to hold the epsilon closure.
--
-- hashval is the hash value for the dfa corresponding to the state set
procedure Epsclosure (T : in out Int_Ptr;
Ns_Addr : in out Integer;
Accset : in out Int_Ptr;
Nacc_Addr, Hv_Addr : out Integer;
Result : out Int_Ptr) is
Ns, Tsp : Integer;
Numstates, Nacc, Hashval, Transsym, Nfaccnum : Integer;
Stkend : Integer;
Stkpos : Integer;
procedure Mark_State (State : in Integer) is
begin
Trans1 (State) := Trans1 (State) - Marker_Difference;
end Mark_State;
pragma Inline (Mark_State);
function Is_Marked (State : in Integer) return Boolean is
begin
return Trans1 (State) < 0;
end Is_Marked;
pragma Inline (Is_Marked);
procedure Unmark_State (State : in Integer) is
begin
Trans1 (State) := Trans1 (State) + Marker_Difference;
end Unmark_State;
pragma Inline (Unmark_State);
procedure Check_Accept (State : in Integer) is
begin
Nfaccnum := Accptnum (State);
if (Nfaccnum /= Nil) then
Nacc := Nacc + 1;
Accset (Nacc) := Nfaccnum;
end if;
end Check_Accept;
pragma Inline (Check_Accept);
procedure Do_Reallocation is
begin
Current_Max_Dfa_Size :=
Current_Max_Dfa_Size + Max_Dfa_Size_Increment;
Num_Reallocs := Num_Reallocs + 1;
Reallocate_Integer_Array (T, Current_Max_Dfa_Size);
Reallocate_Integer_Array (Stk, Current_Max_Dfa_Size);
end Do_Reallocation;
pragma Inline (Do_Reallocation);
procedure Put_On_Stack (State : in Integer) is
begin
Stkend := Stkend + 1;
if (Stkend >= Current_Max_Dfa_Size) then
Do_Reallocation;
end if;
Stk (Stkend) := State;
Mark_State (State);
end Put_On_Stack;
pragma Inline (Put_On_Stack);
procedure Add_State (State : in Integer) is
begin
Numstates := Numstates + 1;
if (Numstates >= Current_Max_Dfa_Size) then
Do_Reallocation;
end if;
T (Numstates) := State;
Hashval := Hashval + State;
end Add_State;
pragma Inline (Add_State);
procedure Stack_State (State : in Integer) is
begin
Put_On_Stack (State);
Check_Accept (State);
if ((Nfaccnum /= Nil) or (Transchar (State) /= Sym_Epsilon)) then
Add_State (State);
end if;
end Stack_State;
pragma Inline (Stack_State);
begin
Numstates := Ns_Addr;
if (not Did_Stk_Init) then
Stk := Allocate_Integer_Array (Current_Max_Dfa_Size);
Did_Stk_Init := True;
end if;
Nacc := 0;
Stkend := 0;
Hashval := 0;
for Nstate in 1 .. Numstates loop
Ns := T (Nstate);
-- the state could be marked if we've already pushed it onto
-- the stack
if (not Is_Marked (Ns)) then
Put_On_Stack (Ns);
null;
end if;
Check_Accept (Ns);
Hashval := Hashval + Ns;
end loop;
Stkpos := 1;
while (Stkpos <= Stkend) loop
Ns := Stk (Stkpos);
Transsym := Transchar (Ns);
if (Transsym = Sym_Epsilon) then
Tsp := Trans1 (Ns) + Marker_Difference;
if (Tsp /= No_Transition) then
if (not Is_Marked (Tsp)) then
Stack_State (Tsp);
end if;
Tsp := Trans2 (Ns);
if (Tsp /= No_Transition) then
if (not Is_Marked (Tsp)) then
Stack_State (Tsp);
end if;
end if;
end if;
end if;
Stkpos := Stkpos + 1;
end loop;
-- clear out "visit" markers
for Chk_Stkpos in 1 .. Stkend loop
if (Is_Marked (Stk (Chk_Stkpos))) then
Unmark_State (Stk (Chk_Stkpos));
else
Misc.Aflexfatal ("consistency check failed in epsclosure()");
end if;
end loop;
Ns_Addr := Numstates;
Hv_Addr := Hashval;
Nacc_Addr := Nacc;
Result := T;
end Epsclosure;
-- increase_max_dfas - increase the maximum number of DFAs
procedure Increase_Max_Dfas is
begin
Current_Max_Dfas := Current_Max_Dfas + Max_Dfas_Increment;
Num_Reallocs := Num_Reallocs + 1;
Reallocate_Integer_Array (Base, Current_Max_Dfas);
Reallocate_Integer_Array (Def, Current_Max_Dfas);
Reallocate_Integer_Array (Dfasiz, Current_Max_Dfas);
Reallocate_Integer_Array (Accsiz, Current_Max_Dfas);
Reallocate_Integer_Array (Dhash, Current_Max_Dfas);
Reallocate_Int_Ptr_Array (Dss, Current_Max_Dfas);
Reallocate_Dfaacc_Union (Dfaacc, Current_Max_Dfas);
end Increase_Max_Dfas;
-- ntod - convert an ndfa to a dfa
--
-- creates the dfa corresponding to the ndfa we've constructed. the
-- dfa starts out in state #1.
procedure Ntod is
Accset : Int_Ptr;
Ds, Nacc, Newds : Integer;
Duplist, Targfreq, Targstate, State : C_Size_Array;
Symlist : C_Size_Bool_Array;
Hashval, Numstates, Dsize : Integer;
Nset, Dset : Int_Ptr;
Targptr, Totaltrans, I, J, Comstate, Comfreq, Targ : Integer;
Num_Start_States, Todo_Head, Todo_Next : Integer;
Snsresult : Boolean;
Full_Table_Temp_File : File_Type;
Buf : Vstring;
Num_Nxt_States : Integer;
use Text_Io;
-- this is so find_table_space(...) will know where to start looking in
-- chk/nxt for unused records for space to put in the state
begin
Accset := Allocate_Integer_Array (Num_Rules + 1);
Nset := Allocate_Integer_Array (Current_Max_Dfa_Size);
-- the "todo" queue is represented by the head, which is the DFA
-- state currently being processed, and the "next", which is the
-- next DFA state number available (not in use). We depend on the
-- fact that snstods() returns DFA's \in increasing order/, and thus
-- need only know the bounds of the dfas to be processed.
Todo_Head := 0;
Todo_Next := 0;
for Cnt in 0 .. Csize loop
Duplist (Cnt) := Nil;
Symlist (Cnt) := False;
end loop;
for Cnt in 0 .. Num_Rules loop
Accset (Cnt) := Nil;
end loop;
if (Trace) then
Nfa.Dumpnfa (Scset (1));
Text_Io.New_Line (Standard_Error);
Text_Io.New_Line (Standard_Error);
Text_Io.Put (Standard_Error, "DFA Dump:");
Text_Io.New_Line (Standard_Error);
Text_Io.New_Line (Standard_Error);
end if;
Tblcmp.Inittbl;
if (Fulltbl) then
Gen.Do_Sect3_Out;
-- output user code up to ##
Skeleton_Manager.Skelout;
-- declare it "short" because it's a real long-shot that that
-- won't be large enough
begin -- make a temporary file to write yy_nxt array into
Create (Full_Table_Temp_File, Out_File);
exception
when Use_Error | Name_Error =>
Misc.Aflexfatal ("can't create temporary file");
end;
Num_Nxt_States := 1;
Text_Io.Put (Full_Table_Temp_File, "( ");
-- generate 0 entries for state #0
for Cnt in 0 .. Numecs loop
Misc.Mk2data (Full_Table_Temp_File, 0);
end loop;
Text_Io.Put (Full_Table_Temp_File, " )");
-- force extra blank line next dataflush()
Dataline := Numdatalines;
end if;
-- create the first states
Num_Start_States := Lastsc * 2;
for Cnt in 1 .. Num_Start_States loop
Numstates := 1;
-- for each start condition, make one state for the case when
-- we're at the beginning of the line (the '%' operator) and
-- one for the case when we're not
if (Cnt mod 2 = 1) then
Nset (Numstates) := Scset ((Cnt / 2) + 1);
else
Nset (Numstates) := Nfa.Mkbranch
(Scbol (Cnt / 2), Scset (Cnt / 2));
end if;
Dfa.Epsclosure (Nset, Numstates, Accset, Nacc, Hashval, Nset);
Snstods (Nset, Numstates, Accset, Nacc, Hashval, Ds, Snsresult);
if (Snsresult) then
Numas := Numas + Nacc;
Totnst := Totnst + Numstates;
Todo_Next := Todo_Next + 1;
if (Variable_Trailing_Context_Rules and (Nacc > 0)) then
Check_Trailing_Context (Nset, Numstates, Accset, Nacc);
end if;
end if;
end loop;
Snstods (Nset, 0, Accset, 0, 0, End_Of_Buffer_State, Snsresult);
if (not Snsresult) then
Misc.Aflexfatal ("could not create unique end-of-buffer state");
end if;
Numas := Numas + 1;
Num_Start_States := Num_Start_States + 1;
Todo_Next := Todo_Next + 1;
while (Todo_Head < Todo_Next) loop
Num_Nxt_States := Num_Nxt_States + 1;
Targptr := 0;
Totaltrans := 0;
for State_Cnt in 1 .. Numecs loop
State (State_Cnt) := 0;
end loop;
Todo_Head := Todo_Head + 1;
Ds := Todo_Head;
Dset := Dss (Ds);
Dsize := Dfasiz (Ds);
if (Trace) then
Text_Io.Put (Standard_Error, "state # ");
Int_Io.Put (Standard_Error, Ds, 1);
Text_Io.Put_Line (Standard_Error, ":");
end if;
Sympartition (Dset, Dsize, Symlist, Duplist);
for Sym in 1 .. Numecs loop
if (Symlist (Sym)) then
Symlist (Sym) := False;
if (Duplist (Sym) = Nil) then
-- symbol has unique out-transitions
Numstates := Symfollowset (Dset, Dsize, Sym, Nset);
Dfa.Epsclosure (Nset, Numstates, Accset,
Nacc, Hashval, Nset);
Snstods (Nset, Numstates, Accset, Nacc,
Hashval, Newds, Snsresult);
if (Snsresult) then
Totnst := Totnst + Numstates;
Todo_Next := Todo_Next + 1;
Numas := Numas + Nacc;
if (Variable_Trailing_Context_Rules and
(Nacc > 0)) then
Check_Trailing_Context
(Nset, Numstates, Accset, Nacc);
end if;
end if;
State (Sym) := Newds;
if (Trace) then
Text_Io.Put (Standard_Error, Ascii.Ht);
Int_Io.Put (Standard_Error, Sym, 1);
Text_Io.Put (Standard_Error, Ascii.Ht);
Int_Io.Put (Standard_Error, Newds, 1);
Text_Io.New_Line (Standard_Error);
end if;
Targptr := Targptr + 1;
Targfreq (Targptr) := 1;
Targstate (Targptr) := Newds;
Numuniq := Numuniq + 1;
else
-- sym's equivalence class has the same transitions
-- as duplist(sym)'s equivalence class
Targ := State (Duplist (Sym));
State (Sym) := Targ;
if (Trace) then
Text_Io.Put (Standard_Error, Ascii.Ht);
Int_Io.Put (Standard_Error, Sym, 1);
Text_Io.Put (Standard_Error, Ascii.Ht);
Int_Io.Put (Standard_Error, Targ, 1);
Text_Io.New_Line (Standard_Error);
end if;
-- update frequency count for destination state
I := 1;
while (Targstate (I) /= Targ) loop
I := I + 1;
end loop;
Targfreq (I) := Targfreq (I) + 1;
Numdup := Numdup + 1;
end if;
Totaltrans := Totaltrans + 1;
Duplist (Sym) := Nil;
end if;
end loop;
Numsnpairs := Numsnpairs + Totaltrans;
if (Caseins and not Useecs) then
I := Character'Pos ('A');
J := Character'Pos ('a');
while (I < Character'Pos ('Z')) loop
State (I) := State (J);
I := I + 1;
J := J + 1;
end loop;
end if;
if (Ds > Num_Start_States) then
Check_For_Backtracking (Ds, State);
end if;
if (Fulltbl) then
-- supply array's 0-element
Text_Io.Put (Full_Table_Temp_File, ",");
Misc.Dataflush (Full_Table_Temp_File);
Text_Io.Put (Full_Table_Temp_File, "( ");
if (Ds = End_Of_Buffer_State) then
Misc.Mk2data (Full_Table_Temp_File, -End_Of_Buffer_State);
else
Misc.Mk2data (Full_Table_Temp_File, End_Of_Buffer_State);
end if;
for Cnt in 1 .. Numecs loop
-- jams are marked by negative of state number
if ((State (Cnt) /= 0)) then
Misc.Mk2data (Full_Table_Temp_File, State (Cnt));
else
Misc.Mk2data (Full_Table_Temp_File, -Ds);
end if;
end loop;
Text_Io.Put (Full_Table_Temp_File, " )");
-- force extra blank line next dataflush()
Dataline := Numdatalines;
else
if (Ds = End_Of_Buffer_State) then
-- special case this state to make sure it does what it's
-- supposed to, i.e., jam on end-of-buffer
Tblcmp.Stack1 (Ds, 0, 0, Jamstate_Const);
else -- normal, compressed state
-- determine which destination state is the most common, and
-- how many transitions to it there are
Comfreq := 0;
Comstate := 0;
for Cnt in 1 .. Targptr loop
if (Targfreq (Cnt) > Comfreq) then
Comfreq := Targfreq (Cnt);
Comstate := Targstate (Cnt);
end if;
end loop;
Tblcmp.Bldtbl (State, Ds, Totaltrans, Comstate, Comfreq);
end if;
end if;
end loop;
if (Fulltbl) then
Text_Io.Put ("yy_nxt : constant array(0..");
Int_Io.Put (Num_Nxt_States - 1, 1);
Text_Io.Put_Line
(" , character'first..character'last) of short :=");
Text_Io.Put_Line (" (");
Reset (Full_Table_Temp_File, In_File);
while (not End_Of_File (Full_Table_Temp_File)) loop
Tstring.Get_Line (Full_Table_Temp_File, Buf);
Tstring.Put_Line (Buf);
end loop;
Delete (Full_Table_Temp_File);
Misc.Dataend;
else
Tblcmp.Cmptmps; -- create compressed template entries
-- create tables for all the states with only one out-transition
while (Onesp > 0) loop
Tblcmp.Mk1tbl (Onestate (Onesp), Onesym (Onesp),
Onenext (Onesp), Onedef (Onesp));
Onesp := Onesp - 1;
end loop;
Tblcmp.Mkdeftbl;
end if;
end Ntod;
-- snstods - converts a set of ndfa states into a dfa state
--
-- on return, the dfa state number is in newds.
procedure Snstods (Sns : in Int_Ptr;
Numstates : in Integer;
Accset : in Int_Ptr;
Nacc, Hashval : in Integer;
Newds_Addr : out Integer;
Result : out Boolean) is
Didsort : Boolean := False;
J : Integer;
Newds : Integer;
Oldsns : Int_Ptr;
begin
for I in 1 .. Lastdfa loop
if (Hashval = Dhash (I)) then
if (Numstates = Dfasiz (I)) then
Oldsns := Dss (I);
if (not Didsort) then
-- we sort the states in sns so we can compare it to
-- oldsns quickly. we use bubble because there probably
-- aren't very many states
Misc.Bubble (Sns, Numstates);
Didsort := True;
end if;
J := 1;
while (J <= Numstates) loop
if (Sns (J) /= Oldsns (J)) then
exit;
end if;
J := J + 1;
end loop;
if (J > Numstates) then
Dfaeql := Dfaeql + 1;
Newds_Addr := I;
Result := False;
return;
end if;
Hshcol := Hshcol + 1;
else
Hshsave := Hshsave + 1;
end if;
end if;
end loop;
-- make a new dfa
Lastdfa := Lastdfa + 1;
if (Lastdfa >= Current_Max_Dfas) then
Increase_Max_Dfas;
end if;
Newds := Lastdfa;
Dss (Newds) := new Unbounded_Int_Array (0 .. Numstates + 1);
-- if we haven't already sorted the states in sns, we do so now, so that
-- future comparisons with it can be made quickly
if (not Didsort) then
Misc.Bubble (Sns, Numstates);
end if;
for I in 1 .. Numstates loop
Dss (Newds) (I) := Sns (I);
end loop;
Dfasiz (Newds) := Numstates;
Dhash (Newds) := Hashval;
if (Nacc = 0) then
Dfaacc (Newds).Dfaacc_State := 0;
Accsiz (Newds) := 0;
else
-- find lowest numbered rule so the disambiguating rule will work
J := Num_Rules + 1;
for I in 1 .. Nacc loop
if (Accset (I) < J) then
J := Accset (I);
end if;
end loop;
Dfaacc (Newds).Dfaacc_State := J;
end if;
Newds_Addr := Newds;
Result := True;
return;
exception
when Storage_Error =>
Misc.Aflexfatal ("dynamic memory failure in snstods()");
end Snstods;
-- symfollowset - follow the symbol transitions one step
function Symfollowset (Ds : in Int_Ptr;
Dsize, Transsym : in Integer;
Nset : in Int_Ptr) return Integer is
Ns, Tsp, Sym, Lenccl, Ch, Numstates, Ccllist : Integer;
begin
Numstates := 0;
for I in 1 .. Dsize loop
-- for each nfa state ns in the state set of ds
Ns := Ds (I);
Sym := Transchar (Ns);
Tsp := Trans1 (Ns);
if (Sym < 0) then
-- it's a character class
Sym := -Sym;
Ccllist := Cclmap (Sym);
Lenccl := Ccllen (Sym);
if (Cclng (Sym) /= 0) then
for J in 0 .. Lenccl - 1 loop
-- loop through negated character class
Ch := Character'Pos (Ccltbl (Ccllist + J));
if (Ch > Transsym) then
exit; -- transsym isn't in negated ccl
else
if (Ch = Transsym) then
goto Bottom; -- next 2
end if;
end if;
end loop;
-- didn't find transsym in ccl
Numstates := Numstates + 1;
Nset (Numstates) := Tsp;
else
for J in 0 .. Lenccl - 1 loop
Ch := Character'Pos (Ccltbl (Ccllist + J));
if (Ch > Transsym) then
exit;
else
if (Ch = Transsym) then
Numstates := Numstates + 1;
Nset (Numstates) := Tsp;
exit;
end if;
end if;
end loop;
end if;
else
if ((Sym >= Character'Pos ('A')) and
(Sym <= Character'Pos ('Z')) and Caseins) then
Misc.Aflexfatal
("consistency check failed in symfollowset");
else
if (Sym = Sym_Epsilon) then
null; -- do nothing
else
if (Ecgroup (Sym) = Transsym) then
Numstates := Numstates + 1;
Nset (Numstates) := Tsp;
end if;
end if;
end if;
end if;
<<Bottom>> null;
end loop;
return Numstates;
end Symfollowset;
-- sympartition - partition characters with same out-transitions
procedure Sympartition (Ds : in Int_Ptr;
Numstates : in Integer;
Symlist : in out C_Size_Bool_Array;
Duplist : in out C_Size_Array) is
Tch, J, Ns, Lenccl, Cclp, Ich : Integer;
Dupfwd : C_Size_Array;
-- partitioning is done by creating equivalence classes for those
-- characters which have out-transitions from the given state. Thus
-- we are really creating equivalence classes of equivalence classes.
begin
for I in 1 .. Numecs loop
-- initialize equivalence class list
Duplist (I) := I - 1;
Dupfwd (I) := I + 1;
end loop;
Duplist (1) := Nil;
Dupfwd (Numecs) := Nil;
Dupfwd (0) := 0;
for I in 1 .. Numstates loop
Ns := Ds (I);
Tch := Transchar (Ns);
if (Tch /= Sym_Epsilon) then
if ((Tch < -Lastccl) or (Tch > Csize)) then
Misc.Aflexfatal
("bad transition character detected in sympartition()");
end if;
if (Tch > 0) then
-- character transition
Ecs.Mkechar (Ecgroup (Tch), Dupfwd, Duplist);
Symlist (Ecgroup (Tch)) := True;
else
-- character class
Tch := -Tch;
Lenccl := Ccllen (Tch);
Cclp := Cclmap (Tch);
Ecs.Mkeccl (Ccltbl (Cclp .. Cclp + Lenccl),
Lenccl, Dupfwd, Duplist, Numecs);
if (Cclng (Tch) /= 0) then
J := 0;
for K in 0 .. Lenccl - 1 loop
Ich := Character'Pos (Ccltbl (Cclp + K));
J := J + 1;
while (J < Ich) loop
Symlist (J) := True;
J := J + 1;
end loop;
end loop;
J := J + 1;
while (J <= Numecs) loop
Symlist (J) := True;
J := J + 1;
end loop;
else
for K in 0 .. Lenccl - 1 loop
Ich := Character'Pos (Ccltbl (Cclp + K));
Symlist (Ich) := True;
end loop;
end if;
end if;
end if;
end loop;
end Sympartition;
end Dfa;
-- Copyright (c) 1990 Regents of the University of California.
-- All rights reserved.
--
-- This software was developed by John Self of the Arcadia project
-- at the University of California, Irvine.
--
-- Redistribution and use in source and binary forms are permitted
-- provided that the above copyright notice and this paragraph are
-- duplicated in all such forms and that any documentation,
-- advertising materials, and other materials related to such
-- distribution and use acknowledge that the software was developed
-- by the University of California, Irvine. The name of the
-- University may not be used to endorse or promote products derived
-- from this software without specific prior written permission.
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-- WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-- TITLE DFA construction routines
-- AUTHOR: John Self (UCI)
-- DESCRIPTION converts non-deterministic finite automatons to finite ones.
-- $Header: /co/ua/self/arcadia/aflex/ada/src/RCS/dfaS.a,v 1.4 90/01/12 15:19:52 self Exp Locker: self $