DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ B T

⟦fb45a0d34⟧ TextFile

    Length: 21173 (0x52b5)
    Types: TextFile
    Names: »B«

Derivation

└─⟦a7d1ea751⟧ Bits:30000550 8mm tape, Rational 1000, !users!projects 94_04_11
    └─ ⟦129cab021⟧ »DATA« 
        └─⟦this⟧ 

TextFile

with Text_Io;
with Bounded_Strings;
with Look_Ahead;
with Error;
package body Lexical is

    Current_Token : Token := L_Eof;
    Current_Value : Lexeme;
    The_File : Text_Io.File_Type;
    Line_Nbr : Positive := 1;
    Column_Nbr : Natural := 0;
    Nbr_Length : Natural := 0;


    package Keywords is
        function Is_Keyword (The_Lexeme : Lexeme) return Boolean;
        function Lexeme_To_Token (From : Lexeme) return Token;
    end Keywords;

    package body Keywords is

        type P_Keyword is access String;
        subtype Keyword_Token is Token range L_Activer .. L_Temporel;
        type Keywords is array (Keyword_Token) of P_Keyword;

        All_Keywords : constant Keywords :=
           (new String'("ACTIVER"), new String'("ALORS"),
            new String'("ATTENDRE"), new String'("AUTEMPS"),
            new String'("AVEC"), new String'("BINAIRE"),
            new String'("CATEGORIE"), new String'("DEBUT"),
            new String'("DESACTIVER"), new String'("DISCRET"),
            new String'("EFFET"), new String'("EN"), new String'("EST"),
            new String'("EVOLUER"), new String'("EXPERIENCE"),
            new String'("FAIRE"), new String'("FIN"), new String'("FOIS"),
            new String'("FUGITIF"), new String'("IMPLANTATION"),
            new String'("JUSQUA"), new String'("MATERIEL"), new String'("MOD"),
            new String'("MODIFIER"), new String'("REPETER"),
            new String'("SCENE"), new String'("SI"), new String'("SINON"),
            new String'("SPECTACLE"), new String'("TEMPOREL"));


        function Is_Keyword (The_Lexeme : Lexeme) return Boolean is
            Word : constant String := Bounded_Strings.Image (The_Lexeme);
        begin
            for I in Keyword_Token loop
                if All_Keywords (I).all = Word then
                    return True;
                end if;
            end loop;
            return False;
        end Is_Keyword;

        function Lexeme_To_Token (From : Lexeme) return Token is
            Word : constant String := Bounded_Strings.Image (From);
        begin
            for I in Keyword_Token loop
                if All_Keywords (I).all = Word then
                    return I;
                end if;
            end loop;
            return L_Id;
        end Lexeme_To_Token;

    end Keywords;


    package Simulated_Automaton is
        procedure Next;
    end Simulated_Automaton;

    package body Simulated_Automaton is

        type State is (St_Start, St_Let, St_Minus, St_Comm, St_Great,
                       St_Less, St_Hexa, St_Nbr, St_Minute,
                       St_Hour, St_Word, St_Second, St_Found);

        subtype Low_Alpha is Character range 'a' .. 'z';
        subtype Upp_Alpha is Character range 'A' .. 'Z';

        subtype Low_Alpha_Hexa is Character range 'a' .. 'f';
        subtype Upp_Alpha_Hexa is Character range 'A' .. 'F';

        subtype Digit is Character range '0' .. '9';

        The_Look_Ahead : Look_Ahead.Object;
        Eol_Flag : Boolean := False;

        procedure File_Next_Char (C : in out Character) is
        begin
            if Eol_Flag then
                Line_Nbr := Line_Nbr + 1;
                Eol_Flag := False;
                if not Look_Ahead.Is_Existing (The_Look_Ahead) then
                    Column_Nbr := 1;
                else
                    Column_Nbr := 0;
                end if;
            else
                Column_Nbr := Column_Nbr + 1;
            end if;
            if Look_Ahead.Is_Existing (The_Look_Ahead) then
                Look_Ahead.Value (The_Look_Ahead, C);
            else
                if At_End then
                    C := Ascii.Eot;
                else
                    if Text_Io.End_Of_Line (The_File) then
                        Text_Io.Skip_Line (The_File);
                        C := Ascii.Lf;
                        Eol_Flag := True;
                    else
                        Text_Io.Get (The_File, C);
                        case C is
                            when Low_Alpha =>
                                C := Character'Val (Character'Pos (C) - 32);
                            when others =>
                                null;
                        end case;
                    end if;
                end if;
            end if;
        exception
            when others =>
                Error.Handle ("lors de la lecture du fichier source !",
                              Error.Internal);
        end File_Next_Char;

        procedure Calculate_Nbr
                     (Hours, Minutes, Seconds, Tenths : in Natural) is
        begin
            Bounded_Strings.Set
               (Current_Value, Integer'Image
                                  (Hours * 3600 * 10 + Minutes * 60 * 10 +
                                   Seconds * 10 + Tenths));
        exception
            when Numeric_Error =>
                Bounded_Strings.Set (Current_Value, Integer'Image (0));
        end Calculate_Nbr;

        procedure Next is
            Current_State : State;
            Current_Char : Character;
            Number : Integer;
            Hours, Minutes, Seconds, Tenths : Natural;
        begin
            if not At_End then
                Bounded_Strings.Free (Current_Value);
                Hours := 0;
                Minutes := 0;
                Seconds := 0;
                Tenths := 0;
                Nbr_Length := 0;
                Current_State := St_Start;
                loop

                    File_Next_Char (Current_Char);
                    case Current_State is

                        when St_Start =>

                            case Current_Char is

                                when Ascii.Eot =>
                                    Current_Token := L_Eof;
                                    Current_State := St_Found;

                                when ' ' | Ascii.Lf | Ascii.Ht =>
                                    null;

                                when '(' =>
                                    Current_Token := L_Open;
                                    Current_State := St_Found;

                                when ')' =>
                                    Current_Token := L_Close;
                                    Current_State := St_Found;

                                when ',' =>
                                    Current_Token := L_Comma;
                                    Current_State := St_Found;

                                when '.' =>
                                    Current_Token := L_Point;
                                    Current_State := St_Found;

                                when ':' =>
                                    Current_State := St_Let;

                                when '+' =>
                                    Current_Token := L_Plus;
                                    Current_State := St_Found;

                                when '-' =>
                                    Current_State := St_Minus;

                                when '*' =>
                                    Current_Token := L_Star;
                                    Current_State := St_Found;

                                when '/' =>
                                    Current_Token := L_Slash;
                                    Current_State := St_Found;

                                when '=' =>
                                    Current_Token := L_Equ;
                                    Current_State := St_Found;

                                when '>' =>
                                    Current_State := St_Great;

                                when '<' =>
                                    Current_State := St_Less;

                                when '#' =>
                                    Current_State := St_Hexa;

                                when Digit =>
                                    Bounded_Strings.Append
                                       (Current_Value, Current_Char);
                                    Current_State := St_Nbr;

                                when Upp_Alpha | '_' =>
                                    Bounded_Strings.Append
                                       (Current_Value, Current_Char);
                                    Current_State := St_Word;

                                when others =>
                                    Current_Token := L_Unk;
                                    Current_State := St_Found;
                            end case;

                        when St_Let =>
                            if Current_Char = '=' then
                                Current_Token := L_Affect;
                                Current_State := St_Found;
                            else
                                Current_Token := L_Unk;
                                Current_State := St_Found;
                            end if;

                        when St_Minus =>
                            if Current_Char = '-' then
                                Current_State := St_Comm;
                            else
                                Look_Ahead.Affect
                                   (The_Look_Ahead, Current_Char);
                                Current_Token := L_Minus;
                                Current_State := St_Found;
                            end if;

                        when St_Comm =>
                            case Current_Char is
                                when Ascii.Lf =>
                                    Current_State := St_Start;
                                when Ascii.Eot =>
                                    Current_Token := L_Eof;
                                    Current_State := St_Found;
                                when others =>
                                    null;
                            end case;

                        when St_Great =>
                            if Current_Char = '=' then
                                Current_Token := L_Geq;
                                Current_State := St_Found;
                            else
                                Look_Ahead.Affect
                                   (The_Look_Ahead, Current_Char);
                                Current_Token := L_Gt;
                                Current_State := St_Found;
                            end if;

                        when St_Less =>
                            case Current_Char is
                                when '=' =>
                                    Current_Token := L_Leq;
                                    Current_State := St_Found;

                                when '>' =>
                                    Current_Token := L_Neq;
                                    Current_State := St_Found;

                                when others =>
                                    Look_Ahead.Affect
                                       (The_Look_Ahead, Current_Char);
                                    Current_Token := L_Lt;
                                    Current_State := St_Found;
                            end case;

                        when St_Hexa =>
                            case Current_Char is
                                when Digit | Upp_Alpha_Hexa =>
                                    Bounded_Strings.Append
                                       (Current_Value, Current_Char);

                                when others =>
                                    Look_Ahead.Affect
                                       (The_Look_Ahead, Current_Char);
                                    Number := Bounded_Strings.To_Number
                                                 (Current_Value, 16);
                                    Bounded_Strings.Free (Current_Value);
                                    Bounded_Strings.Set
                                       (Current_Value, Integer'Image (Number));
                                    Current_Token := L_Nbr;
                                    Current_State := St_Found;
                            end case;

                        when St_Nbr =>
                            case Current_Char is
                                when Digit =>
                                    Nbr_Length := Nbr_Length + 1;
                                    Bounded_Strings.Append
                                       (Current_Value, Current_Char);

                                when 'S' =>
                                    Nbr_Length := Nbr_Length + 1;
                                    Seconds := Lexical.Number;
                                    Current_State := St_Second;
                                    Bounded_Strings.Free (Current_Value);

                                when 'M' =>
                                    Nbr_Length := Nbr_Length + 1;
                                    Current_State := St_Minute;
                                    Minutes := Lexical.Number;
                                    Bounded_Strings.Free (Current_Value);

                                when 'H' =>
                                    Nbr_Length := Nbr_Length + 1;
                                    Current_State := St_Hour;
                                    Hours := Lexical.Number;
                                    Bounded_Strings.Free (Current_Value);

                                when others =>
                                    if Bounded_Strings.Length (Current_Value) /=
                                       0 then
                                        Tenths := Lexical.Number;
                                    end if;
                                    Calculate_Nbr (Hours, Minutes,
                                                   Seconds, Tenths);
                                    Look_Ahead.Affect
                                       (The_Look_Ahead, Current_Char);
                                    Current_Token := L_Nbr;
                                    Current_State := St_Found;
                            end case;

                        when St_Second =>
                            if Current_Char in Digit then
                                Nbr_Length := Nbr_Length + 1;
                                Bounded_Strings.Append
                                   (Current_Value, Current_Char);
                            else
                                if Bounded_Strings.Length (Current_Value) /=
                                   0 then
                                    Tenths := Lexical.Number;
                                end if;
                                Calculate_Nbr (Hours, Minutes, Seconds, Tenths);
                                Look_Ahead.Affect
                                   (The_Look_Ahead, Current_Char);
                                Current_Token := L_Nbr;
                                Current_State := St_Found;
                            end if;

                        when St_Minute =>
                            case Current_Char is
                                when Digit =>
                                    Nbr_Length := Nbr_Length + 1;
                                    Bounded_Strings.Append
                                       (Current_Value, Current_Char);

                                when 'S' =>
                                    Nbr_Length := Nbr_Length + 1;
                                    Seconds := Lexical.Number;
                                    Current_State := St_Second;
                                    Bounded_Strings.Free (Current_Value);

                                when others =>
                                    if Bounded_Strings.Length (Current_Value) /=
                                       0 then
                                        Tenths := Lexical.Number;
                                    end if;
                                    Calculate_Nbr (Hours, Minutes,
                                                   Seconds, Tenths);
                                    Look_Ahead.Affect
                                       (The_Look_Ahead, Current_Char);
                                    Current_Token := L_Nbr;
                                    Current_State := St_Found;
                            end case;

                        when St_Hour =>
                            case Current_Char is
                                when Digit =>
                                    Nbr_Length := Nbr_Length + 1;
                                    Bounded_Strings.Append
                                       (Current_Value, Current_Char);

                                when 'S' =>
                                    Nbr_Length := Nbr_Length + 1;
                                    Current_State := St_Second;
                                    Seconds := Lexical.Number;
                                    Bounded_Strings.Free (Current_Value);

                                when 'M' =>
                                    Nbr_Length := Nbr_Length + 1;
                                    Current_State := St_Minute;
                                    Minutes := Lexical.Number;
                                    Bounded_Strings.Free (Current_Value);

                                when others =>
                                    if Bounded_Strings.Length (Current_Value) /=
                                       0 then
                                        Tenths := Lexical.Number;
                                    end if;
                                    Calculate_Nbr (Hours, Minutes,
                                                   Seconds, Tenths);
                                    Look_Ahead.Affect
                                       (The_Look_Ahead, Current_Char);
                                    Current_Token := L_Nbr;
                                    Current_State := St_Found;
                            end case;

                        when St_Word =>
                            case Current_Char is
                                when Upp_Alpha | '_' | Digit =>
                                    Bounded_Strings.Append
                                       (Current_Value, Current_Char);

                                when others =>
                                    Look_Ahead.Affect
                                       (The_Look_Ahead, Current_Char);
                                    Current_Token :=
                                       Keywords.Lexeme_To_Token (Lexical.Value);
                                    Current_State := St_Found;
                            end case;

                        when St_Found =>
                            null;
                    end case;
                    if Look_Ahead.Is_Existing (The_Look_Ahead) then
                        Column_Nbr := Column_Nbr - 1;
                    end if;
                    exit when Current_State = St_Found;
                end loop;
            else
                Current_Token := L_Eof;
            end if;
        end Next;

    end Simulated_Automaton;


    procedure Open (File_Name : in String) is
    begin
        Text_Io.Open (The_File, Text_Io.In_File, File_Name);
    exception
        when Text_Io.Name_Error =>      -- nom de fichier incorrect
            Error.Handle (File_Name & " est un nom de fichier incorrect !",
                          Error.Internal);
        when others =>
            Error.Handle ("lors de l'ouverture du fichier " & File_Name,
                          Error.Internal);
    end Open;

    function At_End return Boolean is
    begin
        return Text_Io.End_Of_File (The_File);
    exception
        when others =>
            Error.Handle ("lors de l'acces au fichier source !",
                          Error.Internal);
    end At_End;

    procedure Next is
    begin
        Simulated_Automaton.Next;
    end Next;

    function Get return Token is
    begin
        return Current_Token;
    end Get;

    function Value return Lexeme is
    begin
        return Current_Value;
    end Value;

    function Number return Integer is
    begin
        return Integer'Value (Bounded_Strings.Image (Current_Value));
    end Number;

    function Line_Number return Positive is
    begin
        return Line_Nbr;
    end Line_Number;

    function Column_Number return Positive is
    begin
        case Current_Token is
            when L_Open .. L_Equ =>
                return (Column_Nbr);
            when L_Affect .. L_Leq =>
                return (Column_Nbr - 1);
            when L_Nbr =>
                return (Column_Nbr - Nbr_Length);
            when L_Id .. L_Unk =>
                return (Column_Nbr -
                        Bounded_Strings.Length (Current_Value) + 1);
            when L_Eof =>
                return 1;
        end case;
    end Column_Number;

    procedure Close is
    begin
        Text_Io.Close (The_File);
    exception
        when others =>
            Error.Handle ("lors de la fermeture du fichier source !",
                          Error.Internal);
    end Close;

end Lexical;