|
|
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: 27319 (0x6ab7)
Types: TextFile
Names: »B«
└─⟦180fe333a⟧ Bits:30000405 8mm tape, Rational 1000, SW CATALOG, 10_20_0
└─⟦180fe333a⟧ Bits:30000537 8mm tape, Rational 1000, SW Catalog 10_20_0
└─⟦5cb1d1d7f⟧ »DATA«
└─⟦3b1ee7bd8⟧
└─⟦this⟧
separate (Token_Package)
procedure Receive_Symbol (Current_State : in out State;
Current_Token : in out Token;
Previous_Token : in Token;
Present_Buffer : in out Buffer_Value) is
--=============================================================
-- This is the FINITE-STATE MACHINE of the lexical analyzer. ==
-- Receive_Symbol will determine which next STATE shoule be ==
-- taken based on the PRESENT_STATE and current character. ==
--=============================================================
begin
-- Receive_Symbol
case Current_State is
when Start =>
if Source_Io.Is_White_Space (Current_Character) then
-- ignore white space
null;
elsif Source_Io.Is_Letter (Current_Character) then
-- an identifier or a keyword. Label as IDENTIFIER for now.
Label (This_Token => Current_Token,
With_This_Class => Identifier);
-- store current character
Store (Item => Source_Io.To_Upper_Case (Current_Character),
Into => Present_Buffer);
Current_State := Build_Identifier_Or_Keyword;
-- not a blank line
Is_Blank_Line := False;
elsif Source_Io.Is_Digit (Current_Character) then
-- a numeric literal
Label (This_Token => Current_Token,
With_This_Class => Numeric_Literal);
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Numeric_Literal;
Is_Blank_Line := False;
elsif Current_Character = Ascii.Quotation then
-- a string literal (standard format)
Label (This_Token => Current_Token,
With_This_Class => Standard_String_Literal);
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Standard_String_Literal;
Is_Blank_Line := False;
elsif Current_Character = Ascii.Percent then
-- a string literal (alternate format)
Label (This_Token => Current_Token,
With_This_Class => Alternate_String_Literal);
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Alternate_String_Literal;
Is_Blank_Line := False;
elsif Current_Character = ''' then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
-- check whether this is a "tick" or not
if Is_Tick (Previous_Token => Previous_Token) then
Label (This_Token => Current_Token,
With_This_Class => Punctuation);
Current_Token.Content.Enumeration_Value := Apostrophe_Token;
-- needs next character
Source_Io.Get (Item => Current_Character);
Current_State := Stop;
else
-- found a character literal
Label (This_Token => Current_Token,
With_This_Class => Character_Literal);
Current_State := Build_Character_Literal;
end if;
Is_Blank_Line := False;
elsif Source_Io.Is_Comment (Current_Character) then
-- found a comment
Label (This_Token => Current_Token, With_This_Class => Comment);
Skip_Rest_Of_Line;
Is_Blank_Line := False;
Current_State := Stop;
elsif Source_Io.Is_Punctuation (Current_Character) then
-- found a punctuation
Label (This_Token => Current_Token,
With_This_Class => Punctuation);
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
if Source_Io.Is_Compound_Delimiter (Current_Character) then
case Current_Character is
when '=' =>
-- must be an arrow
Current_Token.Content.Enumeration_Value :=
Arrow_Token;
when '.' =>
-- must be double-dot
Current_Token.Content.Enumeration_Value :=
Double_Dot_Token;
when '*' =>
-- must be double star
Current_Token.Content.Enumeration_Value :=
Double_Star_Token;
when ':' =>
-- must be assignment
Current_Token.Content.Enumeration_Value :=
Assignment_Token;
when '/' =>
-- must be inequality
Current_Token.Content.Enumeration_Value :=
Inequality_Token;
when '>' =>
case Source_Io.Peek is
when '=' =>
Current_Token.Content.Enumeration_Value :=
Greater_Than_Or_Equal_Token;
when '>' =>
Current_Token.Content.Enumeration_Value :=
Right_Label_Bracket_Token;
when others =>
null;
end case;
when '<' =>
case Source_Io.Peek is
when '=' =>
Current_Token.Content.Enumeration_Value :=
Less_Than_Or_Equal_Token;
when '<' =>
Current_Token.Content.Enumeration_Value :=
Left_Label_Bracket_Token;
when '>' =>
Current_Token.Content.Enumeration_Value :=
Box_Token;
when others =>
null;
end case;
when others =>
null;
end case; -- compound delimiters
Current_State := Build_Compound_Delimiter;
else
-- simple delimiters
case Current_Character is
when ',' =>
Current_Token.Content.Enumeration_Value :=
Comma_Token;
when '=' =>
Current_Token.Content.Enumeration_Value :=
Equal_Token;
when '.' =>
Current_Token.Content.Enumeration_Value :=
Dot_Token;
when '*' =>
Current_Token.Content.Enumeration_Value :=
Star_Token;
when ':' =>
Current_Token.Content.Enumeration_Value :=
Colon_Token;
when '/' =>
Current_Token.Content.Enumeration_Value :=
Slash_Token;
when '>' =>
Current_Token.Content.Enumeration_Value :=
Greater_Than_Token;
when '<' =>
Current_Token.Content.Enumeration_Value :=
Less_Than_Token;
when '&' =>
Current_Token.Content.Enumeration_Value :=
Ampersand_Token;
when '(' =>
Current_Token.Content.Enumeration_Value :=
Left_Parenthesis_Token;
when ')' =>
Current_Token.Content.Enumeration_Value :=
Right_Parenthesis_Token;
when '+' =>
Current_Token.Content.Enumeration_Value :=
Plus_Token;
when '-' =>
Current_Token.Content.Enumeration_Value :=
Hyphen_Token;
when ';' =>
Current_Token.Content.Enumeration_Value :=
Semicolon_Token;
when '|' =>
Current_Token.Content.Enumeration_Value :=
Vertical_Bar_Token;
when '!' =>
Current_Token.Content.Enumeration_Value :=
Exclamation_Mark_Token;
when others =>
null;
end case; -- simple delimiters
-- needs next character
Source_Io.Get (Item => Current_Character);
Current_State := Stop;
end if;
Is_Blank_Line := False;
elsif Current_Character = Source_Io.New_Line then
if Is_Blank_Line then
Label (This_Token => Current_Token,
With_This_Class => Blank_Line);
else
Label (This_Token => Current_Token,
With_This_Class => New_Line);
Is_Blank_Line := True;
end if;
-- needs next character
Source_Io.Get (Item => Current_Character);
Current_State := Stop;
elsif Current_Character = Source_Io.End_Of_File then
--** changed 12/12/85 by J. Margono
Current_Character := ' ';
Label (This_Token => Current_Token,
With_This_Class => End_Of_File);
Current_State := Stop;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Identifier_Or_Keyword =>
if Source_Io.Is_Letter (Current_Character) or
Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Source_Io.To_Upper_Case (Current_Character),
Into => Present_Buffer);
elsif Current_Character = Ascii.Underline then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Underline_For_Identifier;
elsif Source_Io.Is_White_Space (Current_Character) or
Current_Character = Source_Io.New_Line or
Source_Io.Is_Punctuation (Current_Character) then
Current_State := Stop;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Underline_For_Identifier =>
if Source_Io.Is_Letter (Current_Character) or
Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Source_Io.To_Upper_Case (Current_Character),
Into => Present_Buffer);
Current_State := Build_Identifier_Or_Keyword;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Numeric_Literal =>
if Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
elsif Current_Character = 'E' or Current_Character = 'e' then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Exponent;
elsif Current_Character = Ascii.Underline then
-- do not store underline
Current_State := Build_Underline_For_Numeric_Literal;
elsif Current_Character = '.' then
-- this might be a ".."
if Source_Io.Is_Compound_Delimiter (Current_Character) then
Current_State := Stop;
else
-- a real number
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Real_Literal;
end if;
elsif Current_Character = Ascii.Sharp or
Current_Character = Ascii.Colon then
-- a based literal
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Delimiter := Current_Character;
Current_State := Build_Based_Literal;
elsif Source_Io.Is_White_Space (Current_Character) or
Current_Character = Source_Io.New_Line or
Source_Io.Is_Punctuation (Current_Character) then
-- found a numeric literal
Current_State := Stop;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Underline_For_Numeric_Literal =>
if Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Numeric_Literal;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Real_Literal =>
if Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Rest_Of_Real_Literal;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Rest_Of_Real_Literal =>
if Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
elsif Current_Character = Ascii.Underline then
-- do not store underline
Current_State := Build_Underline_For_Real_Literal;
elsif Current_Character = 'E' or Current_Character = 'e' then
-- store current character
Store (Item => Source_Io.To_Upper_Case (Current_Character),
Into => Present_Buffer);
Current_State := Build_Exponent;
elsif Source_Io.Is_White_Space (Current_Character) or
Current_Character = Source_Io.New_Line or
Source_Io.Is_Punctuation (Current_Character) then
-- found a numeric literal
Current_State := Stop;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Underline_For_Real_Literal =>
if Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Rest_Of_Real_Literal;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Exponent =>
if Current_Character = '+' or Current_Character = '-' then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_First_Digit_Of_Exponent;
elsif Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Rest_Of_Exponent;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_First_Digit_Of_Exponent =>
if Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Rest_Of_Exponent;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Rest_Of_Exponent =>
if Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
elsif Current_Character = Ascii.Underline then
Current_State := Build_Underline_For_Exponent;
elsif Source_Io.Is_White_Space (Current_Character) or
Current_Character = Source_Io.New_Line or
Source_Io.Is_Punctuation (Current_Character) then
-- found a numeric literal
Current_State := Stop;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Underline_For_Exponent =>
if Source_Io.Is_Digit (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Rest_Of_Exponent;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Based_Literal =>
if Source_Io.Is_Extended_Digit (Current_Character) then
-- store current character
Store (Item => Source_Io.To_Upper_Case (Current_Character),
Into => Present_Buffer);
Current_State := Build_Rest_Of_Based_Literal;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Rest_Of_Based_Literal =>
if Source_Io.Is_Extended_Digit (Current_Character) then
-- store current character
Store (Item => Source_Io.To_Upper_Case (Current_Character),
Into => Present_Buffer);
elsif Current_Character = Ascii.Underline then
Current_State := Build_Underline_For_Based_Literal;
elsif Current_Character = Ascii.Sharp or
Current_Character = Ascii.Colon then
-- delimiters must match
if Current_Character = Delimiter then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Optional_Exponent;
else
-- found an illegal character
raise Lexical_Error;
end if;
elsif Current_Character = '.' then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Real_Based_Literal;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Underline_For_Based_Literal =>
if Source_Io.Is_Extended_Digit (Current_Character) then
-- store current character
Store (Item => Source_Io.To_Upper_Case (Current_Character),
Into => Present_Buffer);
Current_State := Build_Rest_Of_Based_Literal;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Optional_Exponent =>
if Current_Character = 'E' or Current_Character = 'e' then
-- store current character
Store (Item => Source_Io.To_Upper_Case (Current_Character),
Into => Present_Buffer);
Current_State := Build_Exponent;
elsif Source_Io.Is_White_Space (Current_Character) or
Current_Character = Source_Io.New_Line or
Source_Io.Is_Punctuation (Current_Character) then
-- found a numeric literal
Current_State := Stop;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Real_Based_Literal =>
if Source_Io.Is_Extended_Digit (Current_Character) then
-- store current character
Store (Item => Source_Io.To_Upper_Case (Current_Character),
Into => Present_Buffer);
Current_State := Build_Rest_Of_Real_Based_Literal;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Rest_Of_Real_Based_Literal =>
if Source_Io.Is_Extended_Digit (Current_Character) then
-- store current character
Store (Item => Source_Io.To_Upper_Case (Current_Character),
Into => Present_Buffer);
elsif Current_Character = Ascii.Underline then
Current_State := Build_Underline_For_Based_Literal;
elsif Current_Character = Ascii.Sharp or
Current_Character = Ascii.Colon then
-- delimiters must match
if Current_Character = Delimiter then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Optional_Exponent;
else
-- found an illegal character
raise Lexical_Error;
end if;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Standard_String_Literal =>
if Source_Io.Is_Non_Quote_Graphic (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
elsif Current_Character = '"' then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Quote_For_String_Literal;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Quote_For_String_Literal =>
if Current_Character = '"' then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Standard_String_Literal;
elsif Source_Io.Is_White_Space (Current_Character) or
Current_Character = Source_Io.New_Line or
Source_Io.Is_Punctuation (Current_Character) then
-- found a standard string literal
Current_State := Stop;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Alternate_String_Literal =>
if Current_Character = Ascii.Percent then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Percent_For_String_Literal;
elsif Source_Io.Is_Non_Quote_Graphic (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Percent_For_String_Literal =>
if Current_Character = Ascii.Percent then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Alternate_String_Literal;
elsif Source_Io.Is_White_Space (Current_Character) or
Current_Character = Source_Io.New_Line or
Source_Io.Is_Punctuation (Current_Character) then
-- found a alternate string literal
Current_State := Stop;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Character_Literal =>
if Source_Io.Is_Graphic (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
Current_State := Build_Rest_Of_Character_Literal;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Rest_Of_Character_Literal =>
if Current_Character = ''' then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
-- needs next character
Source_Io.Get (Item => Current_Character);
Current_State := Stop;
else
-- found an illegal character
raise Lexical_Error;
end if;
when Build_Compound_Delimiter =>
-- i.e., > . * = < >
if Source_Io.Is_Valid_Compound_Delimiter (Current_Character) then
-- store current character
Store (Item => Current_Character, Into => Present_Buffer);
-- needs next character
Source_Io.Get (Item => Current_Character);
Current_State := Stop;
else
-- found an illegal character
raise Lexical_Error;
end if;
when others =>
-- should NOT happen
raise Lexical_Error;
end case;
end Receive_Symbol;