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 - downloadIndex: ┃ B T ┃
Length: 20938 (0x51ca) 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 Misc_Defs, Text_Io, Misc, Int_Io, Tstring, Parse_Tokens; with Scanner, Skeleton_Manager, External_File_Manager; use Misc_Defs, Text_Io, Tstring, Parse_Tokens, External_File_Manager; package body Gen is Indent_Level : Integer := 0; -- each level is 4 spaces Max_Short : constant Integer := 32767; procedure Indent_Up is begin Indent_Level := Indent_Level + 1; end Indent_Up; pragma Inline (Indent_Up); procedure Indent_Down is begin Indent_Level := Indent_Level - 1; end Indent_Down; pragma Inline (Indent_Down); procedure Set_Indent (Indent_Val : in Integer) is begin Indent_Level := Indent_Val; end Set_Indent; -- indent to the current level procedure Do_Indent is I : Integer := Indent_Level * 4; begin while (I >= 8) loop Text_Io.Put (Ascii.Ht); I := I - 8; end loop; while (I > 0) loop Text_Io.Put (' '); I := I - 1; end loop; end Do_Indent; -- generate the code to keep backtracking information procedure Gen_Backtracking is begin if (Num_Backtracking = 0) then return; end if; Indent_Puts ("if ( yy_accept(yy_current_state) /= 0 ) then"); Indent_Up; Indent_Puts ("yy_last_accepting_state := yy_current_state;"); Indent_Puts ("yy_last_accepting_cpos := yy_cp;"); Indent_Down; Indent_Puts ("end if;"); end Gen_Backtracking; -- generate the code to perform the backtrack procedure Gen_Bt_Action is begin if (Num_Backtracking = 0) then return; end if; Set_Indent (4); Indent_Puts ("when 0 => -- must backtrack"); Indent_Puts ("-- undo the effects of YY_DO_BEFORE_ACTION"); Indent_Puts ("yy_ch_buf(yy_cp) := yy_hold_char;"); if (Fulltbl) then Indent_Puts ("yy_cp := yy_last_accepting_cpos + 1;"); else -- backtracking info for compressed tables is taken \after/ -- yy_cp has been incremented for the next state Indent_Puts ("yy_cp := yy_last_accepting_cpos;"); end if; Indent_Puts ("yy_current_state := yy_last_accepting_state;"); Indent_Puts ("goto next_action;"); Text_Io.New_Line; Set_Indent (0); end Gen_Bt_Action; -- generate equivalence-class table procedure Genecs is I : Integer; Numrows : Integer; use Text_Io; begin Text_Io.Put ("yy_ec : constant array(CHARACTER'FIRST.."); Text_Io.Put_Line ("CHARACTER'LAST) of short :="); Text_Io.Put_Line (" ( 0,"); for Char_Count in 1 .. Csize loop if (Caseins and ((Char_Count >= Character'Pos ('A')) and (Char_Count <= Character'Pos ('Z')))) then Ecgroup (Char_Count) := Ecgroup (Misc.Clower (Char_Count)); end if; Ecgroup (Char_Count) := abs (Ecgroup (Char_Count)); Misc.Mkdata (Ecgroup (Char_Count)); end loop; Misc.Dataend; if (Trace) then Text_Io.New_Line (Standard_Error); Text_Io.New_Line (Standard_Error); Text_Io.Put (Standard_Error, "Equivalence Classes:"); Text_Io.New_Line (Standard_Error); Text_Io.New_Line (Standard_Error); Numrows := (Csize + 1) / 8; for J in 1 .. Numrows loop I := J; while (I <= Csize) loop Tstring.Put (Standard_Error, Misc.Readable_Form (Character'Val (I))); Text_Io.Put (Standard_Error, " = "); Int_Io.Put (Standard_Error, Ecgroup (I), 1); Text_Io.Put (Standard_Error, " "); I := I + Numrows; end loop; Text_Io.New_Line (Standard_Error); end loop; end if; end Genecs; -- generate the code to find the action number procedure Gen_Find_Action is begin Indent_Puts ("yy_act := yy_accept(yy_current_state);"); end Gen_Find_Action; -- genftbl - generates full transition table procedure Genftbl is End_Of_Buffer_Action : Integer := Num_Rules + 1; -- *everything* is done in terms of arrays starting at 1, so provide -- a null entry for the zero element of all C arrays use Text_Io; begin Text_Io.Put ("yy_accept : constant array(0.."); Int_Io.Put (Lastdfa, 1); Text_Io.Put_Line (") of short :="); Text_Io.Put_Line (" ( 0,"); Dfaacc (End_Of_Buffer_State).Dfaacc_State := End_Of_Buffer_Action; for I in 1 .. Lastdfa loop declare Anum : Integer := Dfaacc (I).Dfaacc_State; begin Misc.Mkdata (Anum); if (Trace and (Anum /= 0)) then Text_Io.Put (Standard_Error, "state # "); Int_Io.Put (Standard_Error, I, 1); Text_Io.Put (Standard_Error, " accepts: ["); Int_Io.Put (Standard_Error, Anum, 1); Text_Io.Put (Standard_Error, "]"); Text_Io.New_Line (Standard_Error); end if; end; end loop; Misc.Dataend; if (Useecs) then Genecs; end if; -- don't have to dump the actual full table entries - they were created -- on-the-fly end Genftbl; -- generate the code to find the next compressed-table state procedure Gen_Next_Compressed_State is begin if (Useecs) then Indent_Puts ("yy_c := yy_ec(yy_ch_buf(yy_cp));"); else Indent_Puts ("yy_c := yy_ch_buf(yy_cp);"); end if; -- save the backtracking info \before/ computing the next state -- because we always compute one more state than needed - we -- always proceed until we reach a jam state Gen_Backtracking; Indent_Puts ("while ( yy_chk(yy_base(yy_current_state) + yy_c) /= yy_current_state ) loop"); Indent_Up; Indent_Puts ("yy_current_state := yy_def(yy_current_state);"); if (Usemecs) then -- we've arrange it so that templates are never chained -- to one another. This means we can afford make a -- very simple test to see if we need to convert to -- yy_c's meta-equivalence class without worrying -- about erroneously looking up the meta-equivalence -- class twice Do_Indent; -- lastdfa + 2 is the beginning of the templates Text_Io.Put ("if ( yy_current_state >= "); Int_Io.Put (Lastdfa + 2, 1); Text_Io.Put_Line (" ) then"); Indent_Up; Indent_Puts ("yy_c := yy_meta(yy_c);"); Indent_Down; Indent_Puts ("end if;"); end if; Indent_Down; Indent_Puts ("end loop;"); Indent_Puts ("yy_current_state := yy_nxt(yy_base(yy_current_state) + yy_c);"); Indent_Down; end Gen_Next_Compressed_State; -- generate the code to find the next match procedure Gen_Next_Match is -- note - changes in here should be reflected in get_next_state begin if (Fulltbl) then Indent_Puts ("yy_current_state := yy_nxt(yy_current_state, yy_ch_buf(yy_cp));"); Indent_Puts ("while ( yy_current_state > 0 ) loop"); Indent_Up; Indent_Puts ("yy_cp := yy_cp + 1;"); Indent_Puts ("yy_current_state := yy_nxt(yy_current_state, yy_ch_buf(yy_cp));"); Indent_Down; Indent_Puts ("end loop;"); if (Num_Backtracking > 0) then Gen_Backtracking; Text_Io.New_Line; end if; Text_Io.New_Line; Indent_Puts ("yy_current_state := -yy_current_state;"); else -- compressed Indent_Puts ("loop"); Indent_Up; Gen_Next_State; Indent_Puts ("yy_cp := yy_cp + 1;"); if (Interactive) then Text_Io.Put ("if ( yy_base(yy_current_state) = "); Int_Io.Put (Jambase, 1); else Text_Io.Put ("if ( yy_current_state = "); Int_Io.Put (Jamstate, 1); end if; Text_Io.Put_Line (" ) then"); Text_Io.Put_Line (" exit;"); Text_Io.Put_Line ("end if;"); Indent_Down; Do_Indent; Text_Io.Put_Line ("end loop;"); if (not Interactive) then Indent_Puts ("yy_cp := yy_last_accepting_cpos;"); Indent_Puts ("yy_current_state := yy_last_accepting_state;"); end if; end if; end Gen_Next_Match; -- generate the code to find the next state procedure Gen_Next_State is -- note - changes in here should be reflected in get_next_match begin Indent_Up; if (Fulltbl) then Indent_Puts ("yy_current_state := yy_nxt(yy_current_state,"); Indent_Puts (" yy_ch_buf(yy_cp));"); Gen_Backtracking; else Gen_Next_Compressed_State; end if; end Gen_Next_State; -- generate the code to find the start state procedure Gen_Start_State is begin Indent_Puts ("yy_current_state := yy_start;"); if (Bol_Needed) then Indent_Puts ("if ( yy_ch_buf(yy_bp-1) = ASCII.LF ) then"); Indent_Up; Indent_Puts ("yy_current_state := yy_current_state + 1;"); Indent_Down; Indent_Puts ("end if;"); end if; end Gen_Start_State; -- gentabs - generate data statements for the transition tables procedure Gentabs is I, J, K, Nacc, Total_States : Integer; Accset, Acc_Array : Int_Ptr; Accnum : Integer; End_Of_Buffer_Action : Integer := Num_Rules + 1; -- *everything* is done in terms of arrays starting at 1, so provide -- a null entry for the zero element of all C arrays C_Long_Decl : String (1 .. 44) := "static const long int %s[%d] =\n { 0,\n"; C_Short_Decl : String (1 .. 45) := "static const short int %s[%d] =\n { 0,\n"; C_Char_Decl : String (1 .. 40) := "static const char %s[%d] =\n { 0,\n"; begin Acc_Array := Allocate_Integer_Array (Current_Max_Dfas); Nummt := 0; -- the compressed table format jams by entering the "jam state", -- losing information about the previous state in the process. -- In order to recover the previous state, we effectively need -- to keep backtracking information. Num_Backtracking := Num_Backtracking + 1; Dfaacc (End_Of_Buffer_State).Dfaacc_State := End_Of_Buffer_Action; for Cnt in 1 .. Lastdfa loop Acc_Array (Cnt) := Dfaacc (Cnt).Dfaacc_State; end loop; Acc_Array (Lastdfa + 1) := 0; -- add accepting number for the jam state -- spit out ALIST array, dumping the accepting numbers. -- "lastdfa + 2" is the size of ALIST; includes room for arrays -- beginning at 0 and for "jam" state K := Lastdfa + 2; Text_Io.Put ("yy_accept : constant array(0.."); Int_Io.Put (K - 1, 1); Text_Io.Put_Line (") of short :="); Text_Io.Put_Line (" ( 0,"); for Cnt in 1 .. Lastdfa loop Misc.Mkdata (Acc_Array (Cnt)); if (Trace and (Acc_Array (Cnt) /= 0)) then Text_Io.Put (Standard_Error, "state # "); Int_Io.Put (Standard_Error, Cnt, 1); Text_Io.Put (Standard_Error, " accepts: ["); Int_Io.Put (Standard_Error, Acc_Array (Cnt), 1); Text_Io.Put (Standard_Error, ']'); Text_Io.New_Line (Standard_Error); end if; end loop; -- add entry for "jam" state Misc.Mkdata (Acc_Array (Lastdfa + 1)); Misc.Dataend; if (Useecs) then Genecs; end if; if (Usemecs) then -- write out meta-equivalence classes (used to index templates with) if (Trace) then Text_Io.New_Line (Standard_Error); Text_Io.New_Line (Standard_Error); Text_Io.Put_Line (Standard_Error, "Meta-Equivalence Classes:"); end if; Text_Io.Put ("yy_meta : constant array(0.."); Int_Io.Put (Numecs, 1); Text_Io.Put_Line (") of short :="); Text_Io.Put_Line (" ( 0,"); for Cnt in 1 .. Numecs loop if (Trace) then Int_Io.Put (Standard_Error, Cnt, 1); Text_Io.Put (Standard_Error, " = "); Int_Io.Put (Standard_Error, abs (Tecbck (Cnt)), 1); Text_Io.New_Line (Standard_Error); end if; Misc.Mkdata (abs (Tecbck (Cnt))); end loop; Misc.Dataend; end if; Total_States := Lastdfa + Numtemps; Text_Io.Put ("yy_base : constant array(0.."); Int_Io.Put (Total_States, 1); if (Tblend > Max_Short) then Text_Io.Put_Line (") of integer :="); else Text_Io.Put_Line (") of short :="); end if; Text_Io.Put_Line (" ( 0,"); for Cnt in 1 .. Lastdfa loop declare D : Integer := Def (Cnt); begin if (Base (Cnt) = Jamstate_Const) then Base (Cnt) := Jambase; end if; if (D = Jamstate_Const) then Def (Cnt) := Jamstate; else if (D < 0) then -- template reference Tmpuses := Tmpuses + 1; Def (Cnt) := Lastdfa - D + 1; end if; end if; Misc.Mkdata (Base (Cnt)); end; end loop; -- generate jam state's base index I := Lastdfa + 1; Misc.Mkdata (Base (I)); -- skip jam state I := I + 1; for Cnt in I .. Total_States loop Misc.Mkdata (Base (Cnt)); Def (Cnt) := Jamstate; end loop; Misc.Dataend; Text_Io.Put ("yy_def : constant array(0.."); Int_Io.Put (Total_States, 1); if (Tblend > Max_Short) then Text_Io.Put_Line (") of integer :="); else Text_Io.Put_Line (") of short :="); end if; Text_Io.Put_Line (" ( 0,"); for Cnt in 1 .. Total_States loop Misc.Mkdata (Def (Cnt)); end loop; Misc.Dataend; Text_Io.Put ("yy_nxt : constant array(0.."); Int_Io.Put (Tblend, 1); if (Lastdfa > Max_Short) then Text_Io.Put_Line (") of integer :="); else Text_Io.Put_Line (") of short :="); end if; Text_Io.Put_Line (" ( 0,"); for Cnt in 1 .. Tblend loop if ((Nxt (Cnt) = 0) or (Chk (Cnt) = 0)) then Nxt (Cnt) := Jamstate; -- new state is the JAM state end if; Misc.Mkdata (Nxt (Cnt)); end loop; Misc.Dataend; Text_Io.Put ("yy_chk : constant array(0.."); Int_Io.Put (Tblend, 1); if (Lastdfa > Max_Short) then Text_Io.Put_Line (") of integer :="); else Text_Io.Put_Line (") of short :="); end if; Text_Io.Put_Line (" ( 0,"); for Cnt in 1 .. Tblend loop if (Chk (Cnt) = 0) then Nummt := Nummt + 1; end if; Misc.Mkdata (Chk (Cnt)); end loop; Misc.Dataend; exception when Storage_Error => Misc.Aflexfatal ("dynamic memory failure in gentabs()"); end Gentabs; -- write out a string at the current indentation level, adding a final -- newline procedure Indent_Puts (Str : in String) is begin Do_Indent; Text_Io.Put_Line (Str); end Indent_Puts; -- do_sect3_out - dumps section 3. procedure Do_Sect3_Out is Garbage : Token; begin Scanner.Call_Yylex := True; Garbage := Scanner.Get_Token; end Do_Sect3_Out; -- make_tables - generate transition tables -- -- -- Generates transition tables and finishes generating output file procedure Make_Tables is Did_Eof_Rule : Boolean := False; Trans_Offset_Type : String (1 .. 7); Total_Table_Size : Integer := Tblend + Numecs + 1; Buf : Vstring; begin if (not Fulltbl) then -- if we used full tables this is already output Do_Sect3_Out; -- intent of this call is to get everything up to ## Skeleton_Manager.Skelout; -- output YYLex code up to part about tables. end if; Text_Io.Put ("YY_END_OF_BUFFER : constant := "); Int_Io.Put (Num_Rules + 1, 1); Text_Io.Put_Line (";"); Indent_Puts ("subtype yy_state_type is integer;"); Indent_Puts ("yy_current_state : yy_state_type;"); -- now output the constants for the various start conditions Reset (Def_File, In_File); while (not Text_Io.End_Of_File (Def_File)) loop Tstring.Get_Line (Def_File, Buf); Tstring.Put_Line (Buf); end loop; if (Fulltbl) then Genftbl; else Gentabs; end if; Reset (Temp_Action_File, In_File); -- generate code for yy_get_previous_state Set_Indent (1); Skeleton_Manager.Skelout; if (Bol_Needed) then Indent_Puts ("yy_bp : integer := yytext_ptr;"); end if; Skeleton_Manager.Skelout; Gen_Start_State; Skeleton_Manager.Skelout; Gen_Next_State; Skeleton_Manager.Skelout; Set_Indent (2); Indent_Puts ("yy_bp := yy_cp;"); Gen_Start_State; Gen_Next_Match; Skeleton_Manager.Skelout; Set_Indent (3); Gen_Find_Action; Set_Indent (1); Skeleton_Manager.Skelout; Indent_Up; Gen_Bt_Action; Misc.Action_Out; Misc.Action_Out; -- generate cases for any missing EOF rules for I in 1 .. Lastsc loop if (not Sceof (I)) then Do_Indent; if (not Did_Eof_Rule) then Text_Io.Put ("when "); else Text_Io.Put_Line ("|"); end if; Text_Io.Put ("YY_END_OF_BUFFER + "); Tstring.Put (Scname (I)); Text_Io.Put (" + 1 "); Did_Eof_Rule := True; end if; end loop; if (Did_Eof_Rule) then Text_Io.Put_Line ("=> "); end if; if (Did_Eof_Rule) then Indent_Up; Indent_Puts ("return End_Of_Input;"); Indent_Down; end if; Skeleton_Manager.Skelout; -- copy remainder of input to output Misc.Line_Directive_Out; Do_Sect3_Out; -- copy remainder of input, after ##, to the scanner file. end Make_Tables; end Gen; -- 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 scanner generation -- AUTHOR: John Self (UCI) -- DESCRIPTION -- NOTES does actual generation (writing) of output aflex scanners -- $Header: /co/ua/self/arcadia/aflex/ada/src/RCS/genS.a,v 1.4 90/01/12 15:20:07 self Exp Locker: self $