#pragma once
#include <fstream>
#include "memory.h"
#include <iostream>
#include <vector>
#include <cctype>
#include <windows.h>
#include "Lexeme.h"
using namespace std;

#define BUFSIZE 80

namespace Lex
{
struct ints{
int len;
int pos;
int type;
};
enum State {H,ID1, NUM,CHCONST, ASS, DLM, ER, FIN,COM};

enum Type { Type_CC=1, Type_DC=2, Type_CN=3, Type_ID=4};
//Служебные слова
static char *CC[]=  {"and", "not", "program", "int" ,"real", "if", "while", "do", "read", "write", "break", "or","else"};
//Delimiter characters
static char *DC[]=  {"{", "}", "(", ")", ";", "+", "-","<=",">=","!=","==","*", "/", ">", "<", "=", "!",","};
//Служебные слова
static wchar_t *CC2[]=  {L"and", L"not", L"program", L"int" ,L"real", L"if", L"while", L"do", L"read", L"write", L"break", L"or",L"else"};
//Delimiter characters
static wchar_t *DC2[]=  {L"{", L"}", L"(", L")", L";", L"+", L"-",L"<=",L">=",L"!=",L"==",L"*", L"/", L">", L"<", L"=", L"!",L","};
#define BUFSIZE 80
#define TABLEN 1024

class LexAnalyser
{
	char buf[BUFSIZE];
	wchar_t buff[BUFSIZE];
	int nBufPos; // Текушая позиция символа в буфере
	int cur;
	char c; // очередной символ
	wchar_t c2;
	int d; // для формирования числового значения константы
	enum State TC; // Текущее состояние
	vector<Lexeme> LexArray;
	enum LEX_TYPE {LEX_AND,LEX_NOT,LEX_PROG,LEX_INT,LEX_REAL,LEX_IF,LEX_WHILE,LEX_DO, LEX_READ,LEX_WRITE,LEX_BREAK,LEX_OR};

	//CoNstants
	//char* CN[TABLEN];
	vector<char*> CN;
	//int nCN; // Число записей в таблице
	//Identificators
	//char *ID[TABLEN];
	vector<char*> ID;
	//char nID; // Число записей в таблице

public:
	void clear();
	LexAnalyser(void);
	~LexAnalyser(void);
	int Syntax(const wchar_t * stroka,vector<ints> &lexemmes);
	int Analyze(const wchar_t* inFileName, const wchar_t* outFileName);
private:
	//FILE* SetFile(FILE* f);
	void add(void);
	void clear2(void);
	void add2(void);
	int isCC(void);
	int isDC(void);
	int isCC2(void);
	int isDC2(void);
	int AddConstant(void);
	int AddIdent(void);
	char gc(ifstream& f);
	wchar_t gc2(const wchar_t * stroka);
	Lexeme get(int num);
};
}