/* DLGLexerBase.h
 *
 * SOFTWARE RIGHTS
 *
 * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
 * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
 * company may do whatever they wish with source code distributed with
 * PCCTS or the code generated by PCCTS, including the incorporation of
 * PCCTS, or its output, into commerical software.
 *
 * We encourage users to develop software with PCCTS.  However, we do ask
 * that credit is given to us for developing PCCTS.  By "credit",
 * we mean that if you incorporate our source code into one of your
 * programs (commercial product, research project, or otherwise) that you
 * acknowledge this fact somewhere in the documentation, research report,
 * etc...  If you like PCCTS and have developed a nice tool with the
 * output, please mention that you developed it using PCCTS.  In
 * addition, we ask that this header remain intact in our source code.
 * As long as these guidelines are kept, we expect to continue enhancing
 * this system and expect to make other tools available as they are
 * completed.
 *
 * ANTLR 1.33
 * Terence Parr
 * Parr Research Corporation
 * with Purdue University and AHPCRC, University of Minnesota
 * 1989-1998
 */

#ifndef DLGX_H
#define DLGX_H

#include "pcctscfg.h"
#include "pccts_stdio.h"

PCCTS_NAMESPACE_STD

#include ATOKEN_H
#include ATOKENSTREAM_H

class ANTLRParser;              // MR1

/* must define what a char looks like; can make this a class too */
typedef char DLGChar;

/*  Can have it as a class too: (ack this looks weird; is it right?)
class DllExportPCCTS DLGChar {
private:
  int c;
public:
  DLGChar(int ch) { c = ch; }
  int atom() { return c; }
};
*/

/* user must subclass this */
class DllExportPCCTS DLGInputStream {
public:
  virtual int nextChar() = 0;
};

/* Predefined char stream: Input from FILE */
class DllExportPCCTS DLGFileInput : public DLGInputStream {
private:
  int found_eof;
  FILE *input;
public:
  DLGFileInput(FILE *f) { input = f; found_eof = 0; }
  int nextChar() {
      int c;
      if ( found_eof ) return EOF;
      else {
        c=getc(input);
        if ( c==EOF ) found_eof = 1;
        return c;
      }
  }
    void DLGFileReset(FILE *f) {input=f; found_eof = 0; };              // MR11
};

// MR9  Suggested by Bruce Guenter (bruceg@qcc.sk.ca)
// MR9  Make DLGStringInput const correct

/* Predefined char stream: Input from string */
class DllExportPCCTS DLGStringInput : public DLGInputStream {
private:
  const DLGChar *input;                                           // MR9
  const DLGChar *p;                                               // MR9
public:
  DLGStringInput(const DLGChar *s) { input = s; p = &input[0];}   // MR9
  int nextChar()
    {
      if (*p) return (int) (unsigned char) *p++;              // MR14
      else return EOF;
    }

    void DLGStringReset(const DLGChar *s) {input=s; p= &input[0]; }; // MR11 // MR16
};

class DllExportPCCTS DLGState {
public:
  DLGInputStream *input;
  int interactive;
  int track_columns;
  int auto_num;
  int add_erase;
  int lookc;
  int char_full;
  int begcol, endcol;
  int line;
  DLGChar *lextext, *begexpr, *endexpr;
  int bufsize;
  int bufovf;
  DLGChar *nextpos;
  int  class_num;
  int  debugLexerFlag;            // MR1
  ANTLRParser *parser;            // MR1
};

/* user must subclass this */
class DllExportPCCTS DLGLexerBase : public ANTLRTokenStream {
public:
  virtual ANTLRTokenType erraction();

protected:
  DLGInputStream *input;
  int interactive;
  int track_columns;
  DLGChar  *_lextext;  /* text of most recently matched token */
  DLGChar  *_begexpr;  /* beginning of last reg expr recogn. */
  DLGChar  *_endexpr;  /* beginning of last reg expr recogn. */
  int  _bufsize;    /* number of characters in lextext */
  int  _begcol;    /* column that first character of token is in*/
  int  _endcol;    /* column that last character of token is in */
  int  _line;      /* line current token is on */
  int  ch;        /* character to determine next state */
  int  bufovf;      /* indicates that buffer too small for text */
  int  charfull;
  DLGChar  *nextpos;  /* points to next available position in lextext*/
  int  cl;
  int automaton;
  int  add_erase;
  DLGChar ebuf[70];
  _ANTLRTokenPtr token_to_fill;

  int  debugLexerFlag;            // MR1
  ANTLRParser  *parser;          // MR1
public:
  virtual _ANTLRTokenPtr getToken();      // MR12 public
  virtual void advance(void) = 0;
  void  skip(void);    /* erase lextext, look for antoher token */
  void  more(void);    /* keep lextext, look for another token */
  void  mode(int k);  /* switch to automaton 'k' */
  void  saveState(DLGState *);
  void  restoreState(DLGState *);
  virtual ANTLRTokenType nextTokenType(void)=0;/* get next token */
  void  replchar(DLGChar c);  /* replace last recognized reg. expr. with
                   a character */
  void  replstr(const DLGChar *s);  /* replace last recognized reg. expr. with
                       a string */ /* MR20 const */
        virtual int err_in();            // MR1
  virtual void errstd(const char *);        // MR1  MR20 const
  int    line()    { return _line; }
  void  set_line(int newValue)  { _line=newValue; };    // MR1
  virtual void newline()  { _line++; }
  DLGChar  *lextext()  { return _lextext; }

  int    begcol()  { return _begcol; }
  int    endcol()  { return _endcol; }
  void  set_begcol(int a)  { _begcol=a; }
  void  set_endcol(int a)  { _endcol=a; }
  DLGChar  *begexpr()  { return _begexpr; }
  DLGChar  *endexpr()  { return _endexpr; }
  int    bufsize()  { return _bufsize; }

  void  setToken(ANTLRAbstractToken *t)  { token_to_fill = t; }

  void  setInputStream(DLGInputStream *);
  DLGLexerBase(DLGInputStream *in,
         unsigned bufsize=2000,
         int interactive=0,
         int track_columns=0);
  void reset();                  // MR19
  virtual ~DLGLexerBase() { delete [] _lextext; }
  virtual void panic(const char *msg);      // MR1  MR20 const
  void  trackColumns() {
        track_columns = 1;
        this->_begcol = 0;
        this->_endcol = 0;
      };
  virtual ANTLRParser *setParser(ANTLRParser *p);      // MR1
  virtual ANTLRParser *getParser();        // MR1
  virtual int debugLexer(int value);        // MR1
    int     lexErrCount;                            // MR12
};

#endif
