/*
 *  PROJECT: DEMETER SYSTEM
 *  MODULE:  GENERIC PARSER
 *  FILE:    D__scanner.h
 *  SYSTEM:  C++ AT&T version 2.1 on sun3, sun4 and mips, UNIX 4.3 BSD
 *
 *  COPYRIGHT (c) 1990 Northeastern University
 *  Prof. Karl J. Lieberherr
 *
 *  AUTHOR:  Ignacio Silva-Lepe. Originally Chen-Dah Chen.
 *  DATE:    May 14, 1992
 *  REVISED:
 *
 *  DESCRIPTION:
 *  Scanner consists of two abstract classes: D__scanner and D__token.
 *  There exists one global variable of each of these classes.
 *
 */

#ifndef SCANNERDEMH
#define SCANNERDEMH

#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE  1
#endif

#include <stream.h>

enum token_kind
    { END,IDENT,NUMBER,STRING,PATTERN,KEYWORD,REAL_NUMBER,
      TEXT,TOKEN_NOT_RECOGNIZED};

/*
 *  Token hierarchy. One alternative for each kind of token.
 */

class D__token {
 private:
  char* value;
  int   len;
  int line_number;
 public:
  D__token() : value(NULL), len(0), line_number(0) { /* empty */ };
  virtual ~D__token() { /* empty */ }; 

  char* get_value() { return value; }
  void  set_value( char* val_in ) { value = val_in; }
  int   get_len() { return len; }
  void  set_len( int len_in ) { len = len_in; }
  int   get_line_number() { return line_number; }
  void  set_line_number( int ln_in ) { line_number = ln_in; }

  virtual int tokensLeft() { return TRUE; }
  virtual int isIdent() { return FALSE; }
  virtual int isString() { return FALSE; }
  virtual int isPattern() { return FALSE; }
  virtual int matchLL1SetElt( char* ) { return FALSE; }
  virtual int gParseIdent( char* ) = 0;
          int gParseError( char*,char* );
  virtual int gParseString( char* );
};

class D__identToken : public D__token {
 private:
 public:
  int isIdent() { return TRUE; }
  int matchLL1SetElt( char* ll1SetElt )
    { return strcmp( ll1SetElt,"DemIdent" ) == 0; }
  int gParseIdent( char* );
};

class D__numberToken : public D__token {
 private:
 public:
  int matchLL1SetElt( char* ll1SetElt )
    { return strcmp( ll1SetElt,"DemNumber" ) == 0; }
  int gParseIdent( char* );
};

class D__realToken : public D__token {
 private:
 public:
  int matchLL1SetElt( char* ll1SetElt )
    { return strcmp( ll1SetElt,"DemReal" ) == 0; }
  int gParseIdent( char* );
};

class D__stringToken : public D__token {
 private:
 public:
  int isString() { return TRUE; }
  int matchLL1SetElt( char* ll1SetElt )
    { return strcmp( ll1SetElt,"DemString" ) == 0; }
  int gParseIdent( char* );
};

class D__textToken : public D__token {
 private:
 public:
  int matchLL1SetElt( char* ll1SetElt )
    { return strcmp( ll1SetElt,"DemText" ) == 0; }
  int gParseIdent( char* );
};

class D__pattToken : public D__token {
 private:
 public:
  int isPattern() { return TRUE; }
  int matchLL1SetElt( char* ll1SetElt )
    { return strcmp( ll1SetElt,this->get_value() ) == 0; }
  int gParseIdent( char* );
  int gParseString( char* );
};

class D__notToken : public D__token {
 private:
 public:
  int gParseIdent( char* );
};

class D__endToken : public D__token {
 private:
 public:
  int tokensLeft() { return FALSE; }
  int gParseIdent( char* );
  int gParseString( char* );
};

/*
 *  Scanner hierarchy. One alternative for each of user's and dh scanners.
 */

class D__scanner {
 private:
  FILE*     fp;
 public:
  virtual void  set_lex_in( FILE* ) = 0;
  virtual int   lex_lineno() = 0;
  virtual void  set_lex_lineno( int ) = 0;
  virtual int   lex_leng() = 0;
  virtual char* lex_text() = 0;
  virtual int   lex_call() = 0;

  void start(char*);
  void get_sym();
};

extern "C"
{
extern FILE* yyin;
extern char yytext[];
extern int yylineno;
extern int yyleng;
extern int yylex();
}

class D__userScanner : public D__scanner {
 private:
 public:
  void  set_lex_in( FILE* fp_in ) { yyin = fp_in; }
  int   lex_lineno() { return yylineno; }
  void  set_lex_lineno( int ln ) { yylineno = ln; }
  int   lex_leng() { return yyleng; }
  char* lex_text() { return yytext; }
  int lex_call() { return yylex(); }
};

extern "C"
{
extern FILE *zzin;
extern int zzlineno;
extern int zzleng;
extern char zztext[];
extern int zzlex();
}

class D__dhScanner : public D__scanner {
 private:
 public:
  void  set_lex_in( FILE* fp_in ) { zzin = fp_in; }
  int   lex_lineno() { return zzlineno; }
  void  set_lex_lineno( int ln ) { zzlineno = ln; }
  int   lex_leng() { return zzleng; }
  char* lex_text() { return zztext; }
  int   lex_call() { return zzlex(); }
};

extern D__scanner* Scanner;
extern D__token* Token;

#endif

