/* 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
