1. with Ada.Streams.Stream_IO;             use Ada.Streams.Stream_IO; 
  2.  
  3. private with Tokens.Tokenizers; 
  4.  
  5. package Tokens.Scanners is 
  6.  
  7.     -- A Token_Scanner parses and scans a text stream for specific types of 
  8.     -- tokens. Tokens can be optionally accepted from the stream, or expected. 
  9.     -- If a specific token type is expected but a different type is found next, 
  10.     -- a Parse_Exception is raised and the token remains. 
  11.     type Token_Scanner is new Limited_Object with private; 
  12.     type A_Token_Scanner is access all Token_Scanner'Class; 
  13.  
  14.     -- Creates a new Token_Scanner. 
  15.     function Create_Token_Scanner return A_Token_Scanner; 
  16.  
  17.     -- Accepts a valid binary expression operator, as defined by the class 
  18.     -- Binary_Operator. If a valid binary operator is not found, no tokens are 
  19.     -- taken from the stream and null is returned. Token_Exception will be 
  20.     -- raised if an unrecognized or malformed token is encountered; The bad 
  21.     -- token will be discarded and not returned again. 
  22.     function Accept_Binary_Op( this : not null access Token_Scanner'Class ) return A_Token; 
  23.  
  24.     -- Optionally accepts an identifier token. Returns the token if the next in 
  25.     -- the stream is an identifier, otherwise null is returned. This is the 
  26.     -- same as calling Accept_Token( TK_IDENTIFIER ). Token_Exception will be 
  27.     -- raised if an unrecognized or malformed token is encountered; The bad 
  28.     -- token will be discarded and not returned again. 
  29.     function Accept_Identifier( this : not null access Token_Scanner'Class ) return A_Identifier_Token; 
  30.  
  31.     -- Optionally accepts a token of a specific type. Returns the next token 
  32.     -- from the stream if it matches 'tokenType', otherwise the token remains in 
  33.     -- the stream and null is returned. Token_Exception will be raised if an 
  34.     -- unrecognized or malformed token is encountered; The bad token will be 
  35.     -- discarded and not returned again. 
  36.     function Accept_Token( this      : not null access Token_Scanner'Class; 
  37.                            tokenType : Token_Type ) return A_Token; 
  38.  
  39.     -- Optionally accepts a valid unary expression operator, as defined by the 
  40.     -- class Unary_Operator. If a valid unary operator is not found, no tokens 
  41.     -- are taken from the stream and null is returned. Token_Exception will be 
  42.     -- raised if an unrecognized or malformed token is encountered; The bad 
  43.     -- token will be discarded and not returned again. 
  44.     function Accept_Unary_Op( this : not null access Token_Scanner'Class ) return A_Token; 
  45.  
  46.     -- Requires an identifier token to be next. If the next token in the stream 
  47.     -- is not an identifier then Parse_Exception will be raised. Token_Exception 
  48.     -- will be raised if an unrecognized or malformed token is encountered; The 
  49.     -- bad token will be discarded and not returned again. 
  50.     function Expect_Identifier( this : not null access Token_Scanner'Class ) return A_Identifier_Token; 
  51.  
  52.     -- Requires the next token to be of a specific type. Returns the next token 
  53.     -- from the stream if it matches 'tokenType', otherwise the token remains in 
  54.     -- the stream and Parse_Exception is raised. Token_Exception will be raised 
  55.     -- if an unrecognized or malformed token is encountered; The bad token will 
  56.     -- be discarded and not returned again. 
  57.     function Expect_Token( this      : not null access Token_Scanner'Class; 
  58.                            tokenType : Token_Type ) return A_Token; 
  59.  
  60.     -- Requires the next token to be of a specific type. If the next token does 
  61.     -- not match 'tokenType', it will remain in the stream and a Parse_Exception 
  62.     -- will be raised. Otherwise, the expected token will be consumed and the 
  63.     -- procedure will return normally. Token_Exception will be raised if an 
  64.     -- unrecognized or malformed token is encountered; The bad token will be 
  65.     -- discarded and not returned again. 
  66.     procedure Expect( this      : not null access Token_Scanner'Class; 
  67.                       tokenType : Token_Type ); 
  68.  
  69.     -- Returns the current location of the scanner in the input stream. 
  70.     function Get_Location( this : not null access Token_Scanner'Class ) return Token_Location; 
  71.  
  72.     -- Sets the input stream for reading characters. If 'stream' is null, the 
  73.     -- scanner's input will be cleared. 
  74.     procedure Set_Input( this   : not null access Token_Scanner'Class; 
  75.                          stream : Stream_Access ); 
  76.  
  77.     -- Deletes the Token_Scanner; 
  78.     procedure Delete( this : in out A_Token_Scanner ); 
  79.  
  80.     -- Raised when an unexpected token is found. 
  81.     Parse_Exception : exception; 
  82.  
  83. private 
  84.  
  85.     use Tokens.Tokenizers; 
  86.  
  87.     type Token_Scanner is new Limited_Object with 
  88.         record 
  89.             tokenizer : A_Tokenizer := Create_Tokenizer; 
  90.         end record; 
  91.  
  92.     procedure Delete( this : in out Token_Scanner ); 
  93.  
  94.     -- Returns the token on the front of the token stream, regardless of what it 
  95.     -- is. Token_Exception will be raised if an unrecognized token is 
  96.     -- encountered. 
  97.     function Get_Next( this : not null access Token_Scanner'Class ) return A_Token; 
  98.  
  99.     -- Returns a token to the front of the token stream. 'token' is consumed. 
  100.     procedure Push_Back( this  : not null access Token_Scanner'Class; 
  101.                          token : in out A_Token ); 
  102.     pragma Precondition( token /= null ); 
  103.     pragma Postcondition( token = null ); 
  104.  
  105. end Tokens.Scanners;