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