-- $Date: 2003/12/22 13:52:26 $
-- $Revision: 1.8 $
-- $Author: jcrocholl $

with Ada.Strings.Unbounded;
use Ada.Strings.Unbounded;

with Ada.Characters.Latin_1;
use Ada.Characters.Latin_1;

with Ada.Text_IO;
use Ada;

package Parsers is

   -- Private type for instance variables.
   type Parser is private;

   Whitespace : constant String := Space & HT & CR & LF;

   -- Raised by procedure Error.
   Parse_Error : exception;

   -----------------------------
   -- Create and destroy parsers
   -----------------------------

   -- Constructor for a parser on STDIN.
   function Current_Input
     return Parser;

   -- Constructor for a parser on a file.
   function Open
     (File_Name : in String)
     return Parser;

   -- Destructor: free memory and set instance to null.
   procedure Close
     (Parser : in out Parsers.Parser);

   -------------------------
   -- Line-based file access
   -------------------------

   -- Enable / disable the automatic read feature. The default is
   -- False.
   --
   -- If Auto_Read is set to True, the application doesn't need to
   -- call Next_Line because it's done automatically and
   -- transparently.
   procedure Set_Auto_Read
     (Parser    : in Parsers.Parser-- Modify this parser.
      Auto_Read : in Boolean);       -- New value for auto read.

   -- Read next line of input.
   function Next_Line
     (Parser : in Parsers.Parser)
     return Boolean;

   -- Check cursor position. Returns true if and only if the cursor is
   -- at the end of the current line.
   function End_Of_Line
     (Parser : in Parsers.Parser)
     return Boolean;

   -- Check cursor position. Returns true if and only if the end of
   -- input has been reached.
   function End_Of_File
     (Parser : in Parsers.Parser)
     return Boolean;

   -------------------------------------
   -- Advance the cursor unconditionally
   -------------------------------------

   -- Advance cursor position.
   procedure Skip
     (Parser : in Parsers.Parser;
      Count  : in Positive := 1);

   -- Read a character and advance cursor.
   function Skip
     (Parser : in Parsers.Parser)
     return Character;

   -- Read a number of characters.
   function Skip
     (Parser : in Parsers.Parser;
      Count  : in Positive)
     return String;

   --------------------------------------
   -- Read text without moving the cursor
   --------------------------------------

   -- Read a character, don't move cursor.
   function Char
     (Parser : in Parsers.Parser)
     return Character;

   -- Read the rest of the line, don't move cursor.
   function Rest_Of_Line
     (Parser : in Parsers.Parser)
     return String;

   ---------------------------------------
   -- Check if specified text is at cursor
   ---------------------------------------

   -- Check for a character.
   function Found
     (Parser : in Parsers.Parser;
      Char   : in Character)
     return Boolean;

   -- Check for a string.
   function Found
     (Parser : in Parsers.Parser;
      Text   : in String)
     return Boolean;

   -- Check for any one out of a number of characters.
   function Found_Any
     (Parser : in Parsers.Parser;
      Chars  : in String)
     return Boolean;

   -------------------------------------------------------
   -- Check if specified text is at cursor and skip if yes
   -------------------------------------------------------

   -- Skip one character if found.
   function Skip
     (Parser : in Parsers.Parser;
      Char   : in Character)
     return Boolean;

   -- Skip one character if found.
   procedure Skip
     (Parser : in Parsers.Parser;
      Char   : in Character);

   -- Skip a string if found.
   function Skip
     (Parser : in Parsers.Parser;
      Text   : in String)
     return Boolean;

   -- Skip a string if found.
   procedure Skip
     (Parser : in Parsers.Parser;
      Text   : in String);

   -- Skip any out of a number of characters as long as found.
   function Skip_Any
     (Parser : in Parsers.Parser;
      Chars  : in String)
     return Boolean;

   -- Skip any out of a number of characters as long as found.
   procedure Skip_Any
     (Parser : in Parsers.Parser;
      Chars  : in String);

   ------------------------------------
   -- Search forward for specified text
   ------------------------------------

   function Scan
     (Parser : in Parsers.Parser;
      Char   : in Character)
     return Boolean;

   function Scan
     (Parser : in Parsers.Parser;
      Text   : in String)
     return Boolean;

   function Scan_Any
     (Parser : in Parsers.Parser;
      Chars  : in String)
     return Boolean;

   procedure Scan
     (Parser : in Parsers.Parser;
      Char   : in Character);

   procedure Scan
     (Parser : in Parsers.Parser;
      Text   : in String);

   procedure Scan_Any
     (Parser : in Parsers.Parser;
      Chars  : in String);

   -- special reading functions
   function Read_Natural
     (Parser : in Parsers.Parser)
     return Natural;

   function Read_Positive
     (Parser : in Parsers.Parser)
     return Positive;

   function Read_Integer
     (Parser : in Parsers.Parser)
     return Integer;

   function Read_Float
     (Parser : in Parsers.Parser)
     return Float;

   function Read_Word
     (Parser          : in Parsers.Parser;
      Delimiter_Chars : in String := Whitespace)
     return String;

   -- return file name, line and column number for error messages
   function Position
     (Parser : in Parsers.Parser)
     return String;

   -- print an error message to current error
   procedure Warning
     (Parser  : in Parsers.Parser;
      Message : in String);

   -- same as warn plus raise Parse_Error
   procedure Error
     (Parser  : in Parsers.Parser;
      Message : in String);

private

   -- types
   type Parser_Record is record
      File        : Text_IO.File_Type;
      File_Name   : Unbounded_String;
      Line        : Unbounded_String;
      Line_Number : Natural := 0;
      Cursor      : Positive := 1;
      End_Of_File : Boolean := False;
      Auto_Read   : Boolean := False;
   end record;

   type Parser is access Parser_Record;

end Parsers;