\#ifndef JAVACC_JAVACC_H_
\#define JAVACC_JAVACC_H_

\#include <string>
\#include <memory>
\#include <cassert>
\#include <functional>

\#ifndef JAVACC_CHAR_TYPE
\#define JAVACC_CHAR_TYPE char
\#define JAVACC_CHAR_TYPE_SIZEOF 1
\#define JAVACC_CIN  std::cin
\#define JAVACC_COUT std::cout
\#define JAVACC_CERR std::cerr
\#define JAVACC_CLOG std::cout
\#define JAVACC_WIDE(x) #x
\#else
\#define JAVACC_CIN  std::wcin
\#define JAVACC_COUT std::wcout
\#define JAVACC_CERR std::wcerr
\#define JAVACC_CLOG std::wcout
\#define JAVACC_WIDE(x) L#x
\#endif

\#ifndef JAVACC_STRING_TYPE
\#define JAVACC_STRING_TYPE std::basic_string<JAVACC_CHAR_TYPE>
\#endif

\#define JAVACC_SIMPLE_STRING std::basic_string<char>

typedef JAVACC_CHAR_TYPE     JJChar;
typedef JAVACC_STRING_TYPE   JJString;
typedef JAVACC_STRING_TYPE   JJStringBuffer;
typedef JAVACC_SIMPLE_STRING JJSimpleString;

static const JJChar JJEMPTY[] = { 0 };
static const JJChar JJSPACE[] = { ' ', 0 };
static const JJChar JJCOMMA[] = { ',', 0 };
static const JJChar JJQUOTE[] = { '\'', 0 };


// Abstraction on stream classes to read a block of data into a buffer.
class ReaderStream {
public:
  // Read block of data into a buffer and return the actual number read.
  virtual size_t read(JAVACC_CHAR_TYPE *buffer, int offset, size_t len) { return 0; }
  virtual bool   endOfInput() { return true; }
  virtual ~ReaderStream() {}
};

const JAVACC_CHAR_TYPE EMPTY[] = { 0 };

\#ifndef MAX
\#define MAX(a,b) ((a)>=(b)?(a):(b))
\#endif
\#ifndef MIN
\#define MIN(a,b) ((a)<=(b)?(a):(b))
\#endif
\#ifndef null
\#define null 0
\#endif

template<typename T>
struct JJEnter
{
    JJEnter(T f_) : f{f_} {f();}
    ~JJEnter(){}
    T f;
};
template<typename T>
struct JJExit
{
    JJExit(T f_) : f{f_} {}
    ~JJExit(){f();}
    T f;
};

\#endif
