Перейти к публикации
  • Сейчас на странице   Всего пользователей: 6   (0 пользователей, 6 гостей)

Rooster

Программирование[9]

Перепись  

260 пользователей проголосовало

У вас нет прав на голосование в этом опросе, или на просмотр результатов опроса. Пожалуйста, войдите или зарегистрируйтесь для голосования в опросе.

Рекомендованные сообщения

Kant написал 39 минут назад:

и потом всё равно кричать, что в больнице не лечат, дороги плохие и вообще путин пидорас

я плачу ндс при этом


 

очень крутые котейки

RqvSzvr.png


Кому-то пизды дал - нужно сделать скрин обязательно. (с) Solo

Поделиться сообщением


Ссылка на сообщение
Zellar написал 28 минут назад:
E1azor написал 1 час назад:
Zellar написал 2 часа назад:
E1azor написал 2 часа назад:

слышал, что когда меняешь работу или лезешь по карьерной лестнице хуй лучше стоит из-за массажа простаты

дерзай, не ссы

Спасибо, не пришлось долго искать, где ты пишешь хуйню. Ты ее генерируешь по кд

а теперь обоснуй

211ai7eD9+L._SY344_BO1,204,203,200_.jpg Почитай и сам себе обоснуешь

переведи плз не понимаю

 

хз детский сад разводите, 0 конструктива


:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:    всё что пишу -- шизофренический бред     :zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

Поделиться сообщением


Ссылка на сообщение

e1azor скинь свой гитхаб пож
хочу посмотреть что пишешь, куда контрибьютишь. сори, если уже скидывал сюда, искать впадлу

GoldRobot и madvlaydin понравилось это

Найди себе дело по душе и ты не будешь работать ни одного дня в своей жизни

Поделиться сообщением


Ссылка на сообщение
DomikTS- написал 30 минут назад:

e1azor скинь свой гитхаб пож
хочу посмотреть что пишешь, куда контрибьютишь. сори, если уже скидывал сюда, искать впадлу

не выкладываю на гитхаб то что щас пишу или писал ранее


:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:    всё что пишу -- шизофренический бред     :zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

Поделиться сообщением


Ссылка на сообщение

тогда гитлаб дай, ну или битбакет наконец

Поделиться сообщением


Ссылка на сообщение

так-то матерые волки на 5.25 дискетах хранят кодовые базы.

GoldRobot и DomikTS- понравилось это

Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.
 

Поделиться сообщением


Ссылка на сообщение
JuJeu написал 10 минут назад:

5.25 дискетах

в майнкрафте

DomikTS- и GoldRobot понравилось это

 

очень крутые котейки

RqvSzvr.png


Кому-то пизды дал - нужно сделать скрин обязательно. (с) Solo

Поделиться сообщением


Ссылка на сообщение
Just.Doit написал Только что:
JuJeu написал 11 минут назад:

5.25 дискетах

в майнкрафте

:shitpalm:


Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.
 

Поделиться сообщением


Ссылка на сообщение
JuJeu написал 3 минуты назад:

так-то матерые волки на 5.25 дискетах хранят кодовые базы.

Вообще на 3500-футовых плёночных катушках в арктике, да

Крч вероятно буду разбираться с API, а как это делать буду на месте думать. Пообещали белую зп на 10к больше чем в раньше серую предлагали, теперь уже вроде как более-менее, да и рядом с домом.
Ищу в интернетах процесс чтоб в живую поглядеть как это происходит и особо ничего нет, особенно в плане изменений на сайтах, ну что и логично, люди на этом деньги зарабатывают, нашел только интеграцию сберовского эквайринга, вроде не особо сложно, но опять же не ясно что изначально в коде менять, да и я не шарю :D
Завтра пойду говорить за технолигии, пытаться узнать на чем сайты написаны и что к ним нужно подключать.
Вроде это один из сайтов https://sendo-air.ru/


Доброта и взаимовыручка в разделе железо

OK4eIq8maRQ.jpg

Поделиться сообщением


Ссылка на сообщение
(изменено)
madvlaydin написал 3 часа назад:

тогда гитлаб дай, ну или битбакет наконец

уже бегу скидывать тебе свой код который стоит милионы долларов

я кидал исходники каких-то лаб с универа

вот ещё одну лабу могу скинуть, на дрочи  :honkler:

  лаба
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <windows.h>
#include <process.h>

// режим построения программы, в котором выводится
// обратная польская запись токенов в читаемом виде
#define DEBUG

// коды ошибок
#define ERROR_FATAL			-1
#define ERROR_MEMORY		-2
#define ERROR_OVERFLOW		-3

// макросы для вывода ошибок
#define ERR(s, r) {fprintf(out_errors, s); fprintf(out_errors, "\n"); return r;}
#define ERR_NULL_PTR(ptr) {if(ptr == NULL){fprintf(out_errors, "не хватает оперативной памяти\n"); return ERROR_MEMORY;}}
#define ERR_NULL_PTR_STATIC(ptr) {if(ptr == NULL){fprintf(out_errors, "Критическая ошибка: не хватает оперативной памяти для статической таблицы\n"); return ERROR_FATAL;}}
#define ERR_LONG_ID {fprintf(out_errors, "Критическая ошибка: слишком длинное символьное представление идентификатора или константы\n"); return ERROR_FATAL;}
#define ERR_FILE(fid,fname) {if(fid == NULL){fprintf(out_errors, "Критическая ошибка: невозможно открыть файл \"%s\"\n", fname); return ERROR_FATAL;}}
#define DEFRAG(err_id) {if(defrag(err_id) == ERROR_FATAL) {fprintf(out_errors, "Критическая ошибка: не хватает оперативной памяти\n"); return;}}

// макросы устанавливающие является ли символ буквой или цифрой
#define BUKVA(c) ((c >= 'a' && c <='z') || (c >= 'A' && c <='Z') || c == '_')
#define CIFRA(c) ((c >= '0' && c <='9'))

// макрос для вывода в файл листинга
#define PUT(s) {fprintf(out, s); fprintf(out, "\n");}

const char *PHASE_NAME[5] = {"инициализация", "лексический анализ", "синтаксический анализ", "генерация кода", "деинициализация"};

// номера таблиц токенов (условно)
#define KEYS_ID			1
#define OPER_ID			2
#define SEP_ID			3
#define ID_ID			4
#define CONSTS_ID		5
#define WHILE_BEGIN_ID	6
#define WHILE_END_ID	7

// атребуты токета
struct ATR
{
	char *name;
	bool defined;
};

//статическая таблица
struct STATIC_TABLE
{
	int N;							//размер таблицы
	ATR *el;						//массив элементов
	int load(const char *x);		//загрузки таблицы
	int find(const char *x);		//поиск элемента
	void release(void);
};

// динамическая таблица - статическая хеш таблица )
struct TABLE
{
	int N;							// размер
	int count;						// сколько элементов содержит таблица
	ATR *el;						// массив элементов размера N
	int init(const int N0);			// задать размер таблицы
	int save(const char *file_name);// сохранить в файл
	int load(const char *file_name);// загрузить из файла
	bool overflow(const double min_void_hash);	// статус переполненности, если таблица должна быть пуста не менее чем на min_void_hash%
	int resize(const double hash_resize);	// увеличить размер таблицы на hash_resize%
	int find(const char *x);		// найти элемент
	int add(const char *x);			// добавить элемент
	int hash(const char *x, const int iter);	//вычислить хеш функцию (число от 0 до N0-1)
	void release(void);
};

// токен: номер таблицы, номер строки в таблице (индекс)
struct TOKEN
{
	int table;
	int i;
};

// строка таблицы разбора
struct TAB
{
	int to;			// в какое состояние переходить или -1 если следует перейти в состояние из вершины стека либо -2 если это конец программы
	int read;		// нужно ли брать очередной токен из потока токенов
	int save;		// нужно ли сохранять в стеке номер текущего состояния
	int error;		// будет ли ошибка если текущий токен не найден среди токенов из tok[]
	int N;			// количество позволяющих переход токенов в строке
	TOKEN *tok;		// массив из N токенов
	void release(void);
};

// описание таблиц
STATIC_TABLE keys;	//1
STATIC_TABLE oper;	//2
STATIC_TABLE sep;	//3
TABLE id;			//4
TABLE consts;		//5

int *stack;				// стек состояний
int stack_size;
int stack_head;
TOKEN *stack_tokens;	// стек токенов
int stack_tokens_size;
int stack_tokens_head;
TAB *tab;				// таблица разбора
int tab_size;

// размеры
#define STRING_LEN		256	//длинные имена не допускаются
int STACK_LEN;
int STACK_TOKENS_LEN;
int TABLE_ID_LEN;
int TABLE_CONSTS_LEN;

int PHASE_ID;			// Порядковый номер этапа трансляции

// файл для записи ошибок
FILE *out_errors = fopen("_errors.txt","w");

// политика увеличения размера стека и таблиц
#define RESIZE_STACK		0.5
#define RESIZE_HASH			0.5
#define MIN_VOID_HASH		0.9



int STATIC_TABLE::load(const char *file_name)
{
	char next[STRING_LEN];
	char c;
	int i, j;
	FILE *in;
	in = fopen(file_name, "r");
	ERR_FILE(in, file_name);
	fscanf(in, "%d", &N);
	getc(in);
	el = new ATR[N];
	ERR_NULL_PTR_STATIC(el);
	for(i = 0; i < N; i++)
	{
		for(j = 0; ;j++)
		{
			if(j >= STRING_LEN) {ERR_LONG_ID;}
			fscanf(in, "%c", &c);
			if(c == '\n')
			{
				next[j] = 0;
				break;
			}
			next[j] = c;
		}
		el[i].name = new char[strlen(next)+1];
		ERR_NULL_PTR_STATIC(el[i].name);
		strcpy(el[i].name, next);
	}
	fclose(in);
	return 0;
}

int STATIC_TABLE::find(const char *x)
{
	int i1 = 0, i2 = N - 1, i, res;
	for(;;)
	{
		i = (i1 + i2) / 2;
		if(i2 - i1 < 0) break;
		res = strcmp(x, el[i].name);
		if(res < 0)
		{
			i2 = i - 1;
		}else
		if(res > 0)
		{
			i1 = i + 1;
		}else
		if(res == 0) return i;
	}
	return -1;
}

void STATIC_TABLE::release(void)
{
	if(el != NULL)
	{
		for(int i = 0; i < N; i++)
		{
			if(el[i].name != NULL) delete el[i].name;
		}
		delete el;
	}
}

int TABLE::init(const int N0)
{
	N = N0;
	el = new ATR[N];
	ERR_NULL_PTR(el);
	for(int i = 0; i < N; i++)
	{
		el[i].name = NULL;
		el[i].defined = false;
	}
	count = 0;
	return 0;
}

int TABLE::save(const char *file_name)
{
	int i;
	FILE *out;
	out = fopen(file_name, "w");
	ERR_FILE(out, file_name);
	fprintf(out, "%d\n", N);
	for(i = 0; i < N; i++)
	{
		if(el[i].name != NULL)
		{
			fprintf(out, "%d %d %s\n", i, el[i].defined, el[i].name);
		}
	}
	fprintf(out, "-1 -1 -1\n");
	fclose(out);
	return 0;
}

int TABLE::load(const char *file_name)
{
	int i, j;
	bool defined;
	char c;
	char next[STRING_LEN];
	FILE *in;
	in = fopen(file_name, "r");
	ERR_FILE(in, file_name);
	fscanf(in, "%d", &N);
	if(init(N) == ERROR_MEMORY)
	{
		fclose(in);
		return ERROR_FATAL;
	}
	for(;;)
	{
		fscanf(in, "%d%d", &i, &defined);
		el[i].defined = defined;
		if(i == -1) break;
		fscanf(in, "%c", &c);
		for(j = 0; ;j++)
		{
			if(j >= STRING_LEN) {ERR_LONG_ID;}
			fscanf(in, "%c", &c);
			if(c == '\n')
			{
				next[j] = 0;
				break;
			}
			next[j] = c;
		}
		el[i].name = new char[strlen(next)+1];
		ERR_NULL_PTR_STATIC(el[i].name);
		strcpy(el[i].name, next);
		count++;
	}
	fclose(in);
	return 0;
}

bool TABLE::overflow(const double min_void_hash)
{
	return (N - count) / (double)N < min_void_hash;
}

int TABLE::resize(const double hash_resize)
{
	int i, new_N = (int)(N * (1. + hash_resize)) + 1;
	TABLE t;
	t.init(new_N);
	for(i = 0; i < N; i++)
	{
		if(el[i].name != NULL)
		{
			if(t.add(el[i].name) < 0) return ERROR_MEMORY;			
		}
	}
	release();
	*this = t;
	return 0;
}

int TABLE::find(const char *x)
{
	for(int j = 0; j < N; j++)
	{
		int i = hash(x, j);
		if(el[i].name == NULL) return -1;
		if(strcmp(x, el[i].name) == 0) return i;
	}
	return -1;
}

int TABLE::add(const char *x)
{
	if(overflow(MIN_VOID_HASH)) return ERROR_OVERFLOW;
	for(int j = 0; ; j++)
	{
		int i = hash(x, j);
		if(el[i].name == NULL)
		{
			el[i].name = new char[strlen(x) + 1];
			ERR_NULL_PTR(el[i].name);
			strcpy(el[i].name, x);
			el[i].defined = false;
			count++;
			return i;
		}
	}
	return ERROR_OVERFLOW;
}

int TABLE::hash(const char *x, const int iter)
{
	double E = 0;
	for(int i = 0; i < (int)strlen(x); i++)
	{
		E += pow((double)i+2, sin((double)x[i]));
	}
	while(E < 1)
	{
		E *= 2;
	}
	E -= (int)E;
	return ((int)(E * N) + iter*iter)%N;
}

void TABLE::release(void)
{
	if(el != NULL)
	for(int i = 0; i < N; i++)
	{
		if(el[i].name != NULL) delete el[i].name;
	}
	delete el;

}

int write_token(FILE *f, int table, int i)
{
	fprintf(f, "%d	%d\n", table, i);
	return 0;
}

bool token_equal(TOKEN &t1, TOKEN &t2)
{
	return (t1.table == t2.table) && (t1.table >= 4 || t1.i == t2.i);
}

char *get_token_string(TOKEN &t)
{
	if(t.table == 1) return keys.el[t.i].name;
	if(t.table == 2) return oper.el[t.i].name;
	if(t.table == 3) return sep.el[t.i].name;
	if(t.table == 4)
	{
		if(t.i == -1)
		{
			return "идентификатор";
		}
		else
		{
			return id.el[t.i].name;
		}
	}
	if(t.table == 5)
	{
		if(t.i == -1)
		{
			return "константа";
		}
		else
		{
			return consts.el[t.i].name;
		}
	}
#if defined(DEBUG)
	if(t.table == 6)	//начало цикла while
	{
		char *ttt = new char[256];
		sprintf(ttt, "%s %d", "While{", t.i);
		return ttt;
		//return "While{";
	}
	if(t.table == 7)	//конец цикла while
	{
		char *ttt = new char[256];
		sprintf(ttt, "%s %d", "}", t.i);
		return ttt;
		//return "}";
	}
#endif
	ERR("Критическая ошибка: не правильно задан номер таблицы\n", NULL);
}

// увеличивает размеры стека
int increace_stack()
{
	int new_len;
	// увеличение стека
	if(stack_head >= STACK_LEN)
	{
		new_len = (int)(STACK_LEN * (1 + RESIZE_STACK)) + 1;
		int *mem = new int[new_len];
		ERR_NULL_PTR(mem);
		memcpy(mem, stack, sizeof(int) * STACK_LEN);
		STACK_LEN = new_len;
		delete stack;
		stack = mem;
#if defined(DEBUG)
		printf("размер стека состояний изменен до %d, число элементов = %d\n", STACK_LEN, stack_head + 1);
#endif
		return 0;
	}else
	if(stack_tokens_head >= STACK_TOKENS_LEN)
	{
		new_len = (int)(STACK_TOKENS_LEN * (1 + RESIZE_STACK)) + 1;
		TOKEN *mem = new TOKEN[new_len];
		ERR_NULL_PTR(mem);
		memcpy(mem, stack_tokens, sizeof(TOKEN) * STACK_TOKENS_LEN);
		STACK_TOKENS_LEN = new_len;
		delete stack_tokens;
		stack_tokens = mem;
#if defined(DEBUG)
		printf("размер стека токенов изменен до %d, число элементов = %d\n", STACK_TOKENS_LEN, stack_tokens_head + 1);
#endif
		return 0;
	}
	return ERROR_FATAL;
}


// увеличивает размер хеш таблицы
int increace_table()
{
	if(id.overflow(MIN_VOID_HASH))
	{
		if(id.resize(RESIZE_HASH) != 0) ERR("Не хватает памяти, чтобы увеличить размер таблицы идентификаторов", ERROR_MEMORY);
#if defined(DEBUG)
		printf("размер таблицы идентификаторов изменен до %d, число элементов = %d\n", id.N, id.count);
#endif
		return 0;
	}
	if(consts.overflow(MIN_VOID_HASH))
	{
		if(consts.resize(RESIZE_HASH) != 0) ERR("Не хватает памяти, чтобы увеличить размер таблицы констант", ERROR_MEMORY);
#if defined(DEBUG)
		printf("размер таблицы констант изменен до %d, число элементов = %d\n", consts.N, consts.count);
#endif
		return 0;
	}
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// ЛЕКСИЧЕСКИЙ АНАЛИЗАТОР
///////////////////////////////////////////////////////////////////////////////

int make_tokens(const char *file_name_in, const char *file_name_out)
{
	char c;
	char temp[3];
	char word[STRING_LEN];
	int t;
	temp[1] = 0;
	temp[2] = 0;
	FILE *in;
	FILE *out;
	in = fopen(file_name_in, "r");
	ERR_FILE(in, file_name_in);
	out = fopen(file_name_out, "w");
	ERR_FILE(out, file_name_out);
	for(;;)
	{
		c = getc(in);
		temp[0] = c;
// Пробелы
		if(c == ' ' || c == '\n')
		{
		}else
// Комментарии
		if(c == '/')
		{
			c = getc(in);
			if(c == '*')
			{
				for(;;)
				{
					c = getc(in);
					if(c == -1) ERR("неожиданный конец файла внутри комментария", ERROR_FATAL);
					if(c == '*') break;
				}
				c = getc(in);
				if(c != '/') ERR("неожиданный символ в конце комментария", ERROR_FATAL);					
			}
			else
			{
				ERR("неожиданный символ в начале комментария", ERROR_FATAL);
			}
		}else
// Идентификатор или зарезервированное слово
		if(BUKVA(c))
		{
			word[0] = c;
			for(int i = 1; ;i++)
			{
				if(i >= STRING_LEN) {ERR_LONG_ID;}
				c = getc(in);
				if(c == -1) ERR("неожиданный конец файла внутри идентификатора", ERROR_FATAL);
				if(!(BUKVA(c) || CIFRA(c)))
				{
					fseek(in, -1, SEEK_CUR);
					word[i] = 0;
					t = keys.find(word);
					if(t != -1)
					{
						// зарезервированное слово
						write_token(out, KEYS_ID, t);
					}
					else
					{
						// идентификатор
						t = id.find(word);
						if(t != -1)
						{
						// старый идентификатор
							write_token(out, ID_ID, t);
						}
						else
						{
						// новый идентификатор
							t = id.add(word);
							if(t < 0)
							{
								fclose(out);
								fclose(in);
								return t;
							}
							write_token(out, ID_ID, t);
						}
					}
					break;
				}
				word[i] = c;
			}
		}else
// Константа (числовая)
		if(CIFRA(c))
		{
			word[0] = c;
			for(int i = 1; ;i++)
			{
				if(i >= STRING_LEN)
				{
					ERR_LONG_ID;
				}
				c = getc(in);
				if(c == -1) ERR("неожиданный конец файла внутри числовой константы", ERROR_FATAL);
				if(!CIFRA(c))
				{
					fseek(in, -1, SEEK_CUR);
					word[i] = 0;
					t = consts.find(word);
					if(t != -1)
					{
						// старая константа
						write_token(out, CONSTS_ID, t);
					}
					else
					{
						// новая константа
						t = consts.add(word);
						if(t < 0)
						{
							fclose(out);
							fclose(in);
							return t;
						}
						write_token(out, CONSTS_ID, t);
					}
					break;
				}
				word[i] = c;
			}
		}else
// Разделители
		if((t = sep.find(temp)) != -1)
		{
			write_token(out, SEP_ID, t);
		}else
// Знаки операций
		if((t = oper.find(temp)) != -1)
		{
			if(c == '<' || c == '>')
			{
				char cc = getc(in);
				if(cc == '=')
				{
					temp[1] = cc;
					t = oper.find(temp);
					write_token(out, OPER_ID, t);
					temp[1] = 0;
				}
				else
				{
					fseek(in, -1, SEEK_CUR);
					write_token(out, OPER_ID, t);
				}
			}
			else
			write_token(out, OPER_ID, t);
		}else
// Конец файла
		if(c == -1)
		{
			break;
		}else
// Иное (ошибка)
		ERR("недопустимый символ для начала лексемы", ERROR_FATAL);
	}
// завершающий токен

	write_token(out, -1, -1);
	fclose(out);
	fclose(in);
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// СИНТАКСИЧЕСКИЙ АНАЛИЗАТОР
///////////////////////////////////////////////////////////////////////////////

const int STATES_SIMPLE[] =			{37, 44, 46};
const int STATES_BEGIN[] =			{35, 38, 45, 63};		//35 - while, 43 - }
const int STATES_END[] =			{43, 39, 48, 64};
const int STATES_RES_DONT_WRITE[] =	{43, 48};

bool state_simple(int s)
{
	int i;
	for(i = 0; i < 3; i++)
		if(s == STATES_SIMPLE[i]) return true;
	return false;
}
bool state_begin(int s)
{
	int i;
	for(i = 0; i < 4; i++)
		if(s == STATES_BEGIN[i]) return true;
	return false;
}
bool state_end(int s)
{
	int i;
	for(i = 0; i < 4; i++)
		if(s == STATES_END[i]) return true;
	return false;
}
bool state_dont_write(int s)
{
	int i;
	for(i = 0; i < 2; i++)
		if(s == STATES_RES_DONT_WRITE[i]) return true;
	return false;
}

int make_tree(const char *file_name_tab, const char *file_name_tokens, const char *file_name_tree)
{
	FILE *tok_in, *out, *tab_in;
	TOKEN t, t_prev;
// стек для хранения состояний в которые потребуется вернуться
	stack = new int[STACK_LEN];
	ERR_NULL_PTR_STATIC(stack);
// стек для постфикизации токенов
	stack_tokens = new TOKEN[STACK_TOKENS_LEN];
	ERR_NULL_PTR_STATIC(stack_tokens);
	stack_size = 0;
	stack_head = -1;
	stack_tokens_size = 0;
	stack_tokens_head = -1;
	int i, j, s, s_prev, count_whiles;
	bool flag_fined, flag_define, flag_solving;
		// s - текущее состояние из таблицы разбора
		// t - очередной токен
		// s_prev, t_prev - предыдущие


	tab_in = fopen(file_name_tab, "r");
	ERR_FILE(tab_in, file_name_tab);
	tok_in = fopen(file_name_tokens, "r");
	ERR_FILE(tok_in, file_name_tokens);
	out = fopen(file_name_tree, "w");
	ERR_FILE(out, file_name_tree);
	

// считываем таблицу разбора из файла
	fscanf(tab_in, "%d", &tab_size);
	tab = new TAB[tab_size + 1];
	ERR_NULL_PTR_STATIC(tab);
	for(i = 1; i <= tab_size; i++)
	{
		fscanf(tab_in, "%d", &j);				//не нужный номер состояния
		fscanf(tab_in, "%d", &tab[i].to);
		fscanf(tab_in, "%d", &tab[i].read);
		fscanf(tab_in, "%d", &tab[i].save);
		fscanf(tab_in, "%d", &tab[i].error);
		fscanf(tab_in, "%d", &tab[i].N);
		tab[i].tok = new TOKEN[tab[i].N];
		ERR_NULL_PTR_STATIC(tab[i].tok);
		for(j = 0; j < tab[i].N; j++)
		{
			fscanf(tab_in, "%d", &tab[i].tok[j].table);
			fscanf(tab_in, "%d", &tab[i].tok[j].i);
		}
	}
	fclose(tab_in);


// составляем обратную польскую запись дерева программы в соответствии с таблицей разбора грамматики
	s = 1;
	flag_define = false;
	flag_solving = false;
	count_whiles = 0;
	fscanf(tok_in, "%d%d", &t.table, &t.i);
	for(;;)
	{
		//printf("s = %d, t = (%d, %d)\n", s, t.table, t.i);
		//printf("(%d, %d, %d, %d, %d)\n", s, tab[s].to, tab[s].read, tab[s].save, tab[s].error);
		flag_fined = false;
		s_prev = s;
		t_prev = t;
// поиск позволяющих переход токенов
		for(i = 0; i < tab[s].N; i++)
		{
			//printf("(%d, %d) V (%d, %d)\n", t.table, t.i, tab[s].tok[i].table, tab[s].tok[i].i);
			if(token_equal(t, tab[s].tok[i]))
			{
				// читаем новый токен если нужно
				if(tab[s].read)
				{
					fscanf(tok_in, "%d%d", &t.table, &t.i);
				}
				// помещаем в стек номер текущего состояния если нужно
				if(tab[s].save)
				{
					stack_head++;
					if(stack_head >= STACK_LEN)
					{
						if(increace_stack() != 0)	return ERROR_FATAL;
					}
					stack[stack_head] = s;
				}
				// требуется переход в новое состояние либо возврат в состояние из вершины стека
				if(tab[s].to == -2)
				{// конец
					if(stack_head == -1)
					{
						goto end;
					}
					else
					{
						ERR("неожиданный конец программы\n", ERROR_FATAL);
					}
				}else
				if(tab[s].to != -1)
				{
					// переход в новое состояние
					s = tab[s].to;
				}else
				{
					// возврат в состояние из вершины стека
					s = stack[stack_head] + 1;
					stack_head--;
				}
				flag_fined = true;
				break;
			}
		}

// если не найден подходящий токен:
		if(!flag_fined)
		{
			if(!tab[s_prev].error)
			{
				// ничего страшного: ошибки нет, переходим в следующее состояние
				s++;
			}
			else
			{
				// беда
				fprintf(out_errors, "вместо %s ожидалось ", get_token_string(t_prev));
				for(i = 0; i < tab[s_prev].N; i++)
				{
					fprintf(out_errors, "%s", get_token_string(tab[s_prev].tok[i]));
					if(i < tab[s_prev].N - 1) fprintf(out_errors, " или ");
				}
				fprintf(out_errors, "\n");
				return ERROR_FATAL;
			}
		}

// описания переменных
	// если встречается int (состояние 16) значит начинается описание переменных
		if(s_prev == 16)
		{
			flag_define = true;
		}else
	// после ; (состояние 19) описание переменных заканчивается
		if(s_prev == 19)
		{
			flag_define = false;
		}
	// если идет описание переменных и встретился id то обновляем его атрибут defined
		if(flag_define && t_prev.table == 4)
		{
			if(id.el[t_prev.i].defined)
			{
				fprintf(out_errors, "повторное описание переменной %s\n", get_token_string(t_prev));
				return ERROR_FATAL;
			}
			else
			{
				id.el[t_prev.i].defined = true;
			}
		}

// вычисления
	// если встречается while | id (состояние 30) значит начинается использование переменных
		if(s_prev == 30)
		{
			flag_solving = true;
		}else
	// после } (состояние 9) использование переменных заканчивается
		if(s_prev == 9)
		{
			flag_solving = false;
		}
	// если идет использование переменных и встретилась id то проверяем его атрибут defined (вдруг не описана)
		if(flag_solving && t_prev.table == 4)
		{
			if(!id.el[t_prev.i].defined)
			{
				fprintf(out_errors, "не описана переменная %s\n", get_token_string(t_prev));
				return ERROR_FATAL;
			}
		}
// постфикизация
// тут уже выловлены все ошибки
		
		bool res_simple = state_simple(s_prev);	// обычные
		bool res_begin = state_begin(s_prev);	// начинающие
		bool res_end = state_end(s_prev);		// завершающие
		bool res_dont_write = state_dont_write(s_prev);		// не выводить токен?

		if(res_simple || res_begin || res_end)
		{
			// токен начинающий блок помещаем в стек.
			if(res_begin)
			{
				if(s_prev == 35)		//while
				{
					count_whiles++;
					// портим t_prev
					// сразу выводим метку конца начала цикла
					t_prev.table = WHILE_BEGIN_ID;
					t_prev.i = count_whiles;
					write_token(out, t_prev.table, t_prev.i);
#if defined(DEBUG)
					printf("%s\n", get_token_string(t_prev));
#endif
					// а в стек отправляем метку конца цикла
					t_prev.table = WHILE_END_ID;
					t_prev.i = count_whiles;					
				}
				stack_tokens_head++;
				if(stack_tokens_head >= STACK_TOKENS_LEN)
				{
					if(increace_stack() != 0)	return ERROR_FATAL;
				}
				stack_tokens[stack_tokens_head] = t_prev;
			}else
			// токен завершающий блок. Выводим его, если он не в черном списке, затем выводи токен начинающий блок из стека
			if(res_end)
			{
				if(!res_dont_write)
				{
					write_token(out, t_prev.table, t_prev.i);
#if defined(DEBUG)
					printf("%s\n", get_token_string(t_prev));
#endif
				}
				if(stack_tokens_head < 0) ERR("Критическая ошибка: стек токенов пуст\n", ERROR_FATAL);
				write_token(out, stack_tokens[stack_tokens_head].table, stack_tokens[stack_tokens_head].i);
#if defined(DEBUG)
				printf("%s\n", get_token_string(stack_tokens[stack_tokens_head]));
#endif
				stack_tokens_head--;
			}else
			// рядовой символ требующий отображения
			if(res_simple)
			{
				write_token(out, t_prev.table, t_prev.i);
#if defined(DEBUG)
				printf("%s\n", get_token_string(t_prev));
#endif
			}
		}
	}

end:;
// последним должен быть специальный завершающий токен
	fscanf(tok_in, "%d%d", &t.table, &t.i);
	if(t.table != -1 || t.i != -1)
	{
		ERR("лишний код после конца программы\n", ERROR_FATAL);
	}
	write_token(out, -1, -1);// завершающий токен
	fclose(out);
	fclose(tok_in);
	delete stack;
	delete stack_tokens;
	for(i = 1; i <= tab_size; i++)
	{
		delete tab[i].tok;
	}
	delete tab;
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// ГЕНЕРАТОР КОДА
///////////////////////////////////////////////////////////////////////////////

int make_code(const char *file_name_tree, const char *file_name_listing)
{
	FILE *in, *out;
// стек для хранения токенов
	TOKEN t, t1, t2, temp;
	char s[STRING_LEN*2];
	int i;
	in = fopen(file_name_tree, "r");
	ERR_FILE(in, file_name_tree);
	out = fopen(file_name_listing, "w");
	ERR_FILE(out, file_name_listing);
// заголовок программы
	PUT(".386");
	PUT(".MODEL FLAT");
	PUT(".DATA");
// описание переменных
	for(i = 0; i < id.N; i++)
	{
		if(id.el[i].name != NULL)
		{
			sprintf(s, "_%s DD ?", id.el[i].name);
			PUT(s);
		}
	}
// сегмент кода
	PUT(".CODE");
	PUT("START:");
	for(;;)
	{
		// очередной токен
		fscanf(in, "%d%d", &t.table, &t.i);
		if(t.table == -1 && t.i == -1)
			break;
		else
// идентификатор значит дальше будут арифметические операции
		if(t.table == ID_ID)
		{
			// EAX = первое слагаемое
			fscanf(in, "%d%d", &temp.table, &temp.i);		// id | const
			if(temp.table == ID_ID)
				sprintf(s, "MOV EAX, _%s", get_token_string(temp));
			else
				sprintf(s, "MOV EAX, %s", get_token_string(temp));
			PUT(s);
			for(;;)
			{
				fscanf(in, "%d%d", &t1.table, &t1.i);		// id | const | =
				if(t1.table == OPER_ID && t1.i == 4) break;	//=
				//если не равно
				fscanf(in, "%d%d", &t2.table, &t2.i);		// + | -
				if(t2.table == OPER_ID && t2.i == 0)		// +
				{
					if(t1.table == ID_ID)
						sprintf(s, "ADD EAX, _%s", get_token_string(t1));
					else
						sprintf(s, "ADD EAX, %s", get_token_string(t1));
					PUT(s);
				}
				else										// -
				{
					if(t1.table == ID_ID)
						sprintf(s, "SUB EAX, _%s", get_token_string(t1));
					else
						sprintf(s, "SUB EAX, %s", get_token_string(t1));
					PUT(s);
				}
			}
			// приравниваем t = EAX
			sprintf(s, "MOV _%s, EAX", get_token_string(t));
			PUT(s);
		}else
//  начало цикла
		if(t.table == WHILE_BEGIN_ID)
		{
			// ставим метку
			sprintf(s, "WHILE_START%d:", t.i);
			PUT(s);
			// далее идут 2 операнда и знак операции  сравнения
			fscanf(in, "%d%d", &t1.table, &t1.i);		// id | const
			fscanf(in, "%d%d", &t2.table, &t2.i);		// id | const
			fscanf(in, "%d%d", &temp.table, &temp.i);	// < | > | <= | >=
			if(t1.table == ID_ID)
				sprintf(s, "MOV EAX, _%s:", get_token_string(t1));	// EAX = t1
			else
				sprintf(s, "MOV EAX, %s:", get_token_string(t1));
			PUT(s);
			if(t2.table == ID_ID)
				sprintf(s, "CMP EAX, _%s:", get_token_string(t2));	// (t1=EAX) VS t2
			else
				sprintf(s, "CMP EAX, %s:", get_token_string(t2));
			PUT(s);
			if(temp.i == 2)								// <
			{											
				sprintf(s, "JGE WHILE_END%d", t.i);		// >= - условие выхода из цикла
				PUT(s);
			}else
			if(temp.i == 3)								// <=
			{											
				sprintf(s, "JG WHILE_END%d", t.i);		// > - условие выхода из цикла
				PUT(s);
			}else
			if(temp.i == 5)								// >
			{											
				sprintf(s, "JLE WHILE_END%d", t.i);		// <= - условие выхода из цикла
				PUT(s);
			}else
			if(temp.i == 6)								// >=
			{											
				sprintf(s, "JL WHILE_END%d", t.i);		// < - условие выхода из цикла
				PUT(s);
			}			
		}else
//  конец цикла
		if(t.table == WHILE_END_ID)
		{
			// безусловный переход
			sprintf(s, "JMP WHILE_START%d", t.i);
			PUT(s);
			sprintf(s, "WHILE_END%d:", t.i);
			PUT(s);

		}

	}
	PUT("END START");
	fclose(in);
	fclose(out);
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// ГОЛОВНАЯ ПРОГРАММА
///////////////////////////////////////////////////////////////////////////////

unsigned CALLBACK timer_proc(void*)
{
	int count = 0, c;
    while (true)
    {
        Sleep(1*1000);
		count += 60;
        printf("Текущий этап трансляции: %s. Программа выполняется уже %d минут. Прекратить?Y/N ", PHASE_NAME[PHASE_ID], count/60);
		c = getchar();
		if(c == 'y' || c == 'Y') break;
    }
	fprintf(out_errors, "Процесс трансляции прерван по техническим причинам\n");
	_exit(0);
	return 0;
}

void main()
{
	SetConsoleCP(1251);
	SetConsoleOutputCP(1251);
	HANDLE hThread;
	int R;
	FILE *config;
	keys.el = NULL;
	oper.el = NULL;
	sep.el = NULL;
	id.el = NULL;
	consts.el = NULL;
	stack = NULL;
	stack_tokens = NULL;
	tab = NULL;
	config = fopen("config.txt", "r");
	if(config == NULL)
	{
		STACK_LEN			= 1024;
		STACK_TOKENS_LEN	= 1024;
		TABLE_ID_LEN		= 1024;
		TABLE_CONSTS_LEN	= 1024;
	}
	else
	{
		fscanf(config, "%d%d%d%d", &STACK_LEN, &STACK_TOKENS_LEN, &TABLE_ID_LEN, &TABLE_CONSTS_LEN);
		fclose(config);
	}

	PHASE_ID = 0;
	hThread = (HANDLE)_beginthreadex(NULL, 0, timer_proc, NULL, 0, NULL);
	if(keys.load("keys.txt") == ERROR_FATAL) return;
	if(oper.load("oper.txt") == ERROR_FATAL) return;
	if(sep.load("sep.txt") == ERROR_FATAL) return;
	if(id.init(TABLE_ID_LEN) == ERROR_MEMORY) return;
	if(consts.init(TABLE_CONSTS_LEN) == ERROR_MEMORY) return;
	
	PHASE_ID = 1;
m1:	R = make_tokens("code.cpp", "_tokens.txt");
	if(R == ERROR_FATAL) return; else
	if(R == ERROR_OVERFLOW) {if(increace_table() != 0) return; else goto m1;} else
	if(R == ERROR_MEMORY) return;
	id.save("_id.txt"); id.release();
	consts.save("_consts.txt");	consts.release();
		
	PHASE_ID = 2;
	id.load("_id.txt");
	consts.load("_consts.txt");
	R = make_tree("table.txt", "_tokens.txt", "_tree.txt");
	if(R == ERROR_FATAL) return;
	id.save("_id.txt"); id.release();
	consts.save("_consts.txt");	consts.release();
	
	PHASE_ID = 3;
	id.load("_id.txt");
	consts.load("_consts.txt");
	R = make_code("_tree.txt", "_listing.asm");
	if(R == ERROR_FATAL) return;

	PHASE_ID = 4;
	keys.release();
	oper.release();
	sep.release();
	id.release();
	consts.release();
	CloseHandle(hThread);
}

 

 

  картинка для ясности

MAnsXQo.png

 

jDx9OG2.png

вроду эту лабу ещё не скидывал, хз

 

сделано конечно хуёва, особенно хеш таблица

но эта хуета большего не заслуживала


Изменено пользователем E1azor
DomikTS- понравилось это

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:    всё что пишу -- шизофренический бред     :zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

Поделиться сообщением


Ссылка на сообщение
E1azor said 3 hours ago:
madvlaydin said 6 hours ago:

тогда гитлаб дай, ну или битбакет наконец

уже бегу скидывать тебе свой код который стоит милионы долларов

я кидал исходники каких-то лаб с универа

вот ещё одну лабу могу скинуть, на дрочи  :honkler:

  лаба

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <windows.h>
#include <process.h>

// режим построения программы, в котором выводится
// обратная польская запись токенов в читаемом виде
#define DEBUG

// коды ошибок
#define ERROR_FATAL			-1
#define ERROR_MEMORY		-2
#define ERROR_OVERFLOW		-3

// макросы для вывода ошибок
#define ERR(s, r) {fprintf(out_errors, s); fprintf(out_errors, "\n"); return r;}
#define ERR_NULL_PTR(ptr) {if(ptr == NULL){fprintf(out_errors, "не хватает оперативной памяти\n"); return ERROR_MEMORY;}}
#define ERR_NULL_PTR_STATIC(ptr) {if(ptr == NULL){fprintf(out_errors, "Критическая ошибка: не хватает оперативной памяти для статической таблицы\n"); return ERROR_FATAL;}}
#define ERR_LONG_ID {fprintf(out_errors, "Критическая ошибка: слишком длинное символьное представление идентификатора или константы\n"); return ERROR_FATAL;}
#define ERR_FILE(fid,fname) {if(fid == NULL){fprintf(out_errors, "Критическая ошибка: невозможно открыть файл \"%s\"\n", fname); return ERROR_FATAL;}}
#define DEFRAG(err_id) {if(defrag(err_id) == ERROR_FATAL) {fprintf(out_errors, "Критическая ошибка: не хватает оперативной памяти\n"); return;}}

// макросы устанавливающие является ли символ буквой или цифрой
#define BUKVA(c) ((c >= 'a' && c <='z') || (c >= 'A' && c <='Z') || c == '_')
#define CIFRA(c) ((c >= '0' && c <='9'))

// макрос для вывода в файл листинга
#define PUT(s) {fprintf(out, s); fprintf(out, "\n");}

const char *PHASE_NAME[5] = {"инициализация", "лексический анализ", "синтаксический анализ", "генерация кода", "деинициализация"};

// номера таблиц токенов (условно)
#define KEYS_ID			1
#define OPER_ID			2
#define SEP_ID			3
#define ID_ID			4
#define CONSTS_ID		5
#define WHILE_BEGIN_ID	6
#define WHILE_END_ID	7

// атребуты токета
struct ATR
{
	char *name;
	bool defined;
};

//статическая таблица
struct STATIC_TABLE
{
	int N;							//размер таблицы
	ATR *el;						//массив элементов
	int load(const char *x);		//загрузки таблицы
	int find(const char *x);		//поиск элемента
	void release(void);
};

// динамическая таблица - статическая хеш таблица )
struct TABLE
{
	int N;							// размер
	int count;						// сколько элементов содержит таблица
	ATR *el;						// массив элементов размера N
	int init(const int N0);			// задать размер таблицы
	int save(const char *file_name);// сохранить в файл
	int load(const char *file_name);// загрузить из файла
	bool overflow(const double min_void_hash);	// статус переполненности, если таблица должна быть пуста не менее чем на min_void_hash%
	int resize(const double hash_resize);	// увеличить размер таблицы на hash_resize%
	int find(const char *x);		// найти элемент
	int add(const char *x);			// добавить элемент
	int hash(const char *x, const int iter);	//вычислить хеш функцию (число от 0 до N0-1)
	void release(void);
};

// токен: номер таблицы, номер строки в таблице (индекс)
struct TOKEN
{
	int table;
	int i;
};

// строка таблицы разбора
struct TAB
{
	int to;			// в какое состояние переходить или -1 если следует перейти в состояние из вершины стека либо -2 если это конец программы
	int read;		// нужно ли брать очередной токен из потока токенов
	int save;		// нужно ли сохранять в стеке номер текущего состояния
	int error;		// будет ли ошибка если текущий токен не найден среди токенов из tok[]
	int N;			// количество позволяющих переход токенов в строке
	TOKEN *tok;		// массив из N токенов
	void release(void);
};

// описание таблиц
STATIC_TABLE keys;	//1
STATIC_TABLE oper;	//2
STATIC_TABLE sep;	//3
TABLE id;			//4
TABLE consts;		//5

int *stack;				// стек состояний
int stack_size;
int stack_head;
TOKEN *stack_tokens;	// стек токенов
int stack_tokens_size;
int stack_tokens_head;
TAB *tab;				// таблица разбора
int tab_size;

// размеры
#define STRING_LEN		256	//длинные имена не допускаются
int STACK_LEN;
int STACK_TOKENS_LEN;
int TABLE_ID_LEN;
int TABLE_CONSTS_LEN;

int PHASE_ID;			// Порядковый номер этапа трансляции

// файл для записи ошибок
FILE *out_errors = fopen("_errors.txt","w");

// политика увеличения размера стека и таблиц
#define RESIZE_STACK		0.5
#define RESIZE_HASH			0.5
#define MIN_VOID_HASH		0.9



int STATIC_TABLE::load(const char *file_name)
{
	char next[STRING_LEN];
	char c;
	int i, j;
	FILE *in;
	in = fopen(file_name, "r");
	ERR_FILE(in, file_name);
	fscanf(in, "%d", &N);
	getc(in);
	el = new ATR[N];
	ERR_NULL_PTR_STATIC(el);
	for(i = 0; i < N; i++)
	{
		for(j = 0; ;j++)
		{
			if(j >= STRING_LEN) {ERR_LONG_ID;}
			fscanf(in, "%c", &c);
			if(c == '\n')
			{
				next[j] = 0;
				break;
			}
			next[j] = c;
		}
		el[i].name = new char[strlen(next)+1];
		ERR_NULL_PTR_STATIC(el[i].name);
		strcpy(el[i].name, next);
	}
	fclose(in);
	return 0;
}

int STATIC_TABLE::find(const char *x)
{
	int i1 = 0, i2 = N - 1, i, res;
	for(;;)
	{
		i = (i1 + i2) / 2;
		if(i2 - i1 < 0) break;
		res = strcmp(x, el[i].name);
		if(res < 0)
		{
			i2 = i - 1;
		}else
		if(res > 0)
		{
			i1 = i + 1;
		}else
		if(res == 0) return i;
	}
	return -1;
}

void STATIC_TABLE::release(void)
{
	if(el != NULL)
	{
		for(int i = 0; i < N; i++)
		{
			if(el[i].name != NULL) delete el[i].name;
		}
		delete el;
	}
}

int TABLE::init(const int N0)
{
	N = N0;
	el = new ATR[N];
	ERR_NULL_PTR(el);
	for(int i = 0; i < N; i++)
	{
		el[i].name = NULL;
		el[i].defined = false;
	}
	count = 0;
	return 0;
}

int TABLE::save(const char *file_name)
{
	int i;
	FILE *out;
	out = fopen(file_name, "w");
	ERR_FILE(out, file_name);
	fprintf(out, "%d\n", N);
	for(i = 0; i < N; i++)
	{
		if(el[i].name != NULL)
		{
			fprintf(out, "%d %d %s\n", i, el[i].defined, el[i].name);
		}
	}
	fprintf(out, "-1 -1 -1\n");
	fclose(out);
	return 0;
}

int TABLE::load(const char *file_name)
{
	int i, j;
	bool defined;
	char c;
	char next[STRING_LEN];
	FILE *in;
	in = fopen(file_name, "r");
	ERR_FILE(in, file_name);
	fscanf(in, "%d", &N);
	if(init(N) == ERROR_MEMORY)
	{
		fclose(in);
		return ERROR_FATAL;
	}
	for(;;)
	{
		fscanf(in, "%d%d", &i, &defined);
		el[i].defined = defined;
		if(i == -1) break;
		fscanf(in, "%c", &c);
		for(j = 0; ;j++)
		{
			if(j >= STRING_LEN) {ERR_LONG_ID;}
			fscanf(in, "%c", &c);
			if(c == '\n')
			{
				next[j] = 0;
				break;
			}
			next[j] = c;
		}
		el[i].name = new char[strlen(next)+1];
		ERR_NULL_PTR_STATIC(el[i].name);
		strcpy(el[i].name, next);
		count++;
	}
	fclose(in);
	return 0;
}

bool TABLE::overflow(const double min_void_hash)
{
	return (N - count) / (double)N < min_void_hash;
}

int TABLE::resize(const double hash_resize)
{
	int i, new_N = (int)(N * (1. + hash_resize)) + 1;
	TABLE t;
	t.init(new_N);
	for(i = 0; i < N; i++)
	{
		if(el[i].name != NULL)
		{
			if(t.add(el[i].name) < 0) return ERROR_MEMORY;			
		}
	}
	release();
	*this = t;
	return 0;
}

int TABLE::find(const char *x)
{
	for(int j = 0; j < N; j++)
	{
		int i = hash(x, j);
		if(el[i].name == NULL) return -1;
		if(strcmp(x, el[i].name) == 0) return i;
	}
	return -1;
}

int TABLE::add(const char *x)
{
	if(overflow(MIN_VOID_HASH)) return ERROR_OVERFLOW;
	for(int j = 0; ; j++)
	{
		int i = hash(x, j);
		if(el[i].name == NULL)
		{
			el[i].name = new char[strlen(x) + 1];
			ERR_NULL_PTR(el[i].name);
			strcpy(el[i].name, x);
			el[i].defined = false;
			count++;
			return i;
		}
	}
	return ERROR_OVERFLOW;
}

int TABLE::hash(const char *x, const int iter)
{
	double E = 0;
	for(int i = 0; i < (int)strlen(x); i++)
	{
		E += pow((double)i+2, sin((double)x[i]));
	}
	while(E < 1)
	{
		E *= 2;
	}
	E -= (int)E;
	return ((int)(E * N) + iter*iter)%N;
}

void TABLE::release(void)
{
	if(el != NULL)
	for(int i = 0; i < N; i++)
	{
		if(el[i].name != NULL) delete el[i].name;
	}
	delete el;

}

int write_token(FILE *f, int table, int i)
{
	fprintf(f, "%d	%d\n", table, i);
	return 0;
}

bool token_equal(TOKEN &t1, TOKEN &t2)
{
	return (t1.table == t2.table) && (t1.table >= 4 || t1.i == t2.i);
}

char *get_token_string(TOKEN &t)
{
	if(t.table == 1) return keys.el[t.i].name;
	if(t.table == 2) return oper.el[t.i].name;
	if(t.table == 3) return sep.el[t.i].name;
	if(t.table == 4)
	{
		if(t.i == -1)
		{
			return "идентификатор";
		}
		else
		{
			return id.el[t.i].name;
		}
	}
	if(t.table == 5)
	{
		if(t.i == -1)
		{
			return "константа";
		}
		else
		{
			return consts.el[t.i].name;
		}
	}
#if defined(DEBUG)
	if(t.table == 6)	//начало цикла while
	{
		char *ttt = new char[256];
		sprintf(ttt, "%s %d", "While{", t.i);
		return ttt;
		//return "While{";
	}
	if(t.table == 7)	//конец цикла while
	{
		char *ttt = new char[256];
		sprintf(ttt, "%s %d", "}", t.i);
		return ttt;
		//return "}";
	}
#endif
	ERR("Критическая ошибка: не правильно задан номер таблицы\n", NULL);
}

// увеличивает размеры стека
int increace_stack()
{
	int new_len;
	// увеличение стека
	if(stack_head >= STACK_LEN)
	{
		new_len = (int)(STACK_LEN * (1 + RESIZE_STACK)) + 1;
		int *mem = new int[new_len];
		ERR_NULL_PTR(mem);
		memcpy(mem, stack, sizeof(int) * STACK_LEN);
		STACK_LEN = new_len;
		delete stack;
		stack = mem;
#if defined(DEBUG)
		printf("размер стека состояний изменен до %d, число элементов = %d\n", STACK_LEN, stack_head + 1);
#endif
		return 0;
	}else
	if(stack_tokens_head >= STACK_TOKENS_LEN)
	{
		new_len = (int)(STACK_TOKENS_LEN * (1 + RESIZE_STACK)) + 1;
		TOKEN *mem = new TOKEN[new_len];
		ERR_NULL_PTR(mem);
		memcpy(mem, stack_tokens, sizeof(TOKEN) * STACK_TOKENS_LEN);
		STACK_TOKENS_LEN = new_len;
		delete stack_tokens;
		stack_tokens = mem;
#if defined(DEBUG)
		printf("размер стека токенов изменен до %d, число элементов = %d\n", STACK_TOKENS_LEN, stack_tokens_head + 1);
#endif
		return 0;
	}
	return ERROR_FATAL;
}


// увеличивает размер хеш таблицы
int increace_table()
{
	if(id.overflow(MIN_VOID_HASH))
	{
		if(id.resize(RESIZE_HASH) != 0) ERR("Не хватает памяти, чтобы увеличить размер таблицы идентификаторов", ERROR_MEMORY);
#if defined(DEBUG)
		printf("размер таблицы идентификаторов изменен до %d, число элементов = %d\n", id.N, id.count);
#endif
		return 0;
	}
	if(consts.overflow(MIN_VOID_HASH))
	{
		if(consts.resize(RESIZE_HASH) != 0) ERR("Не хватает памяти, чтобы увеличить размер таблицы констант", ERROR_MEMORY);
#if defined(DEBUG)
		printf("размер таблицы констант изменен до %d, число элементов = %d\n", consts.N, consts.count);
#endif
		return 0;
	}
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// ЛЕКСИЧЕСКИЙ АНАЛИЗАТОР
///////////////////////////////////////////////////////////////////////////////

int make_tokens(const char *file_name_in, const char *file_name_out)
{
	char c;
	char temp[3];
	char word[STRING_LEN];
	int t;
	temp[1] = 0;
	temp[2] = 0;
	FILE *in;
	FILE *out;
	in = fopen(file_name_in, "r");
	ERR_FILE(in, file_name_in);
	out = fopen(file_name_out, "w");
	ERR_FILE(out, file_name_out);
	for(;;)
	{
		c = getc(in);
		temp[0] = c;
// Пробелы
		if(c == ' ' || c == '\n')
		{
		}else
// Комментарии
		if(c == '/')
		{
			c = getc(in);
			if(c == '*')
			{
				for(;;)
				{
					c = getc(in);
					if(c == -1) ERR("неожиданный конец файла внутри комментария", ERROR_FATAL);
					if(c == '*') break;
				}
				c = getc(in);
				if(c != '/') ERR("неожиданный символ в конце комментария", ERROR_FATAL);					
			}
			else
			{
				ERR("неожиданный символ в начале комментария", ERROR_FATAL);
			}
		}else
// Идентификатор или зарезервированное слово
		if(BUKVA(c))
		{
			word[0] = c;
			for(int i = 1; ;i++)
			{
				if(i >= STRING_LEN) {ERR_LONG_ID;}
				c = getc(in);
				if(c == -1) ERR("неожиданный конец файла внутри идентификатора", ERROR_FATAL);
				if(!(BUKVA(c) || CIFRA(c)))
				{
					fseek(in, -1, SEEK_CUR);
					word[i] = 0;
					t = keys.find(word);
					if(t != -1)
					{
						// зарезервированное слово
						write_token(out, KEYS_ID, t);
					}
					else
					{
						// идентификатор
						t = id.find(word);
						if(t != -1)
						{
						// старый идентификатор
							write_token(out, ID_ID, t);
						}
						else
						{
						// новый идентификатор
							t = id.add(word);
							if(t < 0)
							{
								fclose(out);
								fclose(in);
								return t;
							}
							write_token(out, ID_ID, t);
						}
					}
					break;
				}
				word[i] = c;
			}
		}else
// Константа (числовая)
		if(CIFRA(c))
		{
			word[0] = c;
			for(int i = 1; ;i++)
			{
				if(i >= STRING_LEN)
				{
					ERR_LONG_ID;
				}
				c = getc(in);
				if(c == -1) ERR("неожиданный конец файла внутри числовой константы", ERROR_FATAL);
				if(!CIFRA(c))
				{
					fseek(in, -1, SEEK_CUR);
					word[i] = 0;
					t = consts.find(word);
					if(t != -1)
					{
						// старая константа
						write_token(out, CONSTS_ID, t);
					}
					else
					{
						// новая константа
						t = consts.add(word);
						if(t < 0)
						{
							fclose(out);
							fclose(in);
							return t;
						}
						write_token(out, CONSTS_ID, t);
					}
					break;
				}
				word[i] = c;
			}
		}else
// Разделители
		if((t = sep.find(temp)) != -1)
		{
			write_token(out, SEP_ID, t);
		}else
// Знаки операций
		if((t = oper.find(temp)) != -1)
		{
			if(c == '<' || c == '>')
			{
				char cc = getc(in);
				if(cc == '=')
				{
					temp[1] = cc;
					t = oper.find(temp);
					write_token(out, OPER_ID, t);
					temp[1] = 0;
				}
				else
				{
					fseek(in, -1, SEEK_CUR);
					write_token(out, OPER_ID, t);
				}
			}
			else
			write_token(out, OPER_ID, t);
		}else
// Конец файла
		if(c == -1)
		{
			break;
		}else
// Иное (ошибка)
		ERR("недопустимый символ для начала лексемы", ERROR_FATAL);
	}
// завершающий токен

	write_token(out, -1, -1);
	fclose(out);
	fclose(in);
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// СИНТАКСИЧЕСКИЙ АНАЛИЗАТОР
///////////////////////////////////////////////////////////////////////////////

const int STATES_SIMPLE[] =			{37, 44, 46};
const int STATES_BEGIN[] =			{35, 38, 45, 63};		//35 - while, 43 - }
const int STATES_END[] =			{43, 39, 48, 64};
const int STATES_RES_DONT_WRITE[] =	{43, 48};

bool state_simple(int s)
{
	int i;
	for(i = 0; i < 3; i++)
		if(s == STATES_SIMPLE[i]) return true;
	return false;
}
bool state_begin(int s)
{
	int i;
	for(i = 0; i < 4; i++)
		if(s == STATES_BEGIN[i]) return true;
	return false;
}
bool state_end(int s)
{
	int i;
	for(i = 0; i < 4; i++)
		if(s == STATES_END[i]) return true;
	return false;
}
bool state_dont_write(int s)
{
	int i;
	for(i = 0; i < 2; i++)
		if(s == STATES_RES_DONT_WRITE[i]) return true;
	return false;
}

int make_tree(const char *file_name_tab, const char *file_name_tokens, const char *file_name_tree)
{
	FILE *tok_in, *out, *tab_in;
	TOKEN t, t_prev;
// стек для хранения состояний в которые потребуется вернуться
	stack = new int[STACK_LEN];
	ERR_NULL_PTR_STATIC(stack);
// стек для постфикизации токенов
	stack_tokens = new TOKEN[STACK_TOKENS_LEN];
	ERR_NULL_PTR_STATIC(stack_tokens);
	stack_size = 0;
	stack_head = -1;
	stack_tokens_size = 0;
	stack_tokens_head = -1;
	int i, j, s, s_prev, count_whiles;
	bool flag_fined, flag_define, flag_solving;
		// s - текущее состояние из таблицы разбора
		// t - очередной токен
		// s_prev, t_prev - предыдущие


	tab_in = fopen(file_name_tab, "r");
	ERR_FILE(tab_in, file_name_tab);
	tok_in = fopen(file_name_tokens, "r");
	ERR_FILE(tok_in, file_name_tokens);
	out = fopen(file_name_tree, "w");
	ERR_FILE(out, file_name_tree);
	

// считываем таблицу разбора из файла
	fscanf(tab_in, "%d", &tab_size);
	tab = new TAB[tab_size + 1];
	ERR_NULL_PTR_STATIC(tab);
	for(i = 1; i <= tab_size; i++)
	{
		fscanf(tab_in, "%d", &j);				//не нужный номер состояния
		fscanf(tab_in, "%d", &tab[i].to);
		fscanf(tab_in, "%d", &tab[i].read);
		fscanf(tab_in, "%d", &tab[i].save);
		fscanf(tab_in, "%d", &tab[i].error);
		fscanf(tab_in, "%d", &tab[i].N);
		tab[i].tok = new TOKEN[tab[i].N];
		ERR_NULL_PTR_STATIC(tab[i].tok);
		for(j = 0; j < tab[i].N; j++)
		{
			fscanf(tab_in, "%d", &tab[i].tok[j].table);
			fscanf(tab_in, "%d", &tab[i].tok[j].i);
		}
	}
	fclose(tab_in);


// составляем обратную польскую запись дерева программы в соответствии с таблицей разбора грамматики
	s = 1;
	flag_define = false;
	flag_solving = false;
	count_whiles = 0;
	fscanf(tok_in, "%d%d", &t.table, &t.i);
	for(;;)
	{
		//printf("s = %d, t = (%d, %d)\n", s, t.table, t.i);
		//printf("(%d, %d, %d, %d, %d)\n", s, tab[s].to, tab[s].read, tab[s].save, tab[s].error);
		flag_fined = false;
		s_prev = s;
		t_prev = t;
// поиск позволяющих переход токенов
		for(i = 0; i < tab[s].N; i++)
		{
			//printf("(%d, %d) V (%d, %d)\n", t.table, t.i, tab[s].tok[i].table, tab[s].tok[i].i);
			if(token_equal(t, tab[s].tok[i]))
			{
				// читаем новый токен если нужно
				if(tab[s].read)
				{
					fscanf(tok_in, "%d%d", &t.table, &t.i);
				}
				// помещаем в стек номер текущего состояния если нужно
				if(tab[s].save)
				{
					stack_head++;
					if(stack_head >= STACK_LEN)
					{
						if(increace_stack() != 0)	return ERROR_FATAL;
					}
					stack[stack_head] = s;
				}
				// требуется переход в новое состояние либо возврат в состояние из вершины стека
				if(tab[s].to == -2)
				{// конец
					if(stack_head == -1)
					{
						goto end;
					}
					else
					{
						ERR("неожиданный конец программы\n", ERROR_FATAL);
					}
				}else
				if(tab[s].to != -1)
				{
					// переход в новое состояние
					s = tab[s].to;
				}else
				{
					// возврат в состояние из вершины стека
					s = stack[stack_head] + 1;
					stack_head--;
				}
				flag_fined = true;
				break;
			}
		}

// если не найден подходящий токен:
		if(!flag_fined)
		{
			if(!tab[s_prev].error)
			{
				// ничего страшного: ошибки нет, переходим в следующее состояние
				s++;
			}
			else
			{
				// беда
				fprintf(out_errors, "вместо %s ожидалось ", get_token_string(t_prev));
				for(i = 0; i < tab[s_prev].N; i++)
				{
					fprintf(out_errors, "%s", get_token_string(tab[s_prev].tok[i]));
					if(i < tab[s_prev].N - 1) fprintf(out_errors, " или ");
				}
				fprintf(out_errors, "\n");
				return ERROR_FATAL;
			}
		}

// описания переменных
	// если встречается int (состояние 16) значит начинается описание переменных
		if(s_prev == 16)
		{
			flag_define = true;
		}else
	// после ; (состояние 19) описание переменных заканчивается
		if(s_prev == 19)
		{
			flag_define = false;
		}
	// если идет описание переменных и встретился id то обновляем его атрибут defined
		if(flag_define && t_prev.table == 4)
		{
			if(id.el[t_prev.i].defined)
			{
				fprintf(out_errors, "повторное описание переменной %s\n", get_token_string(t_prev));
				return ERROR_FATAL;
			}
			else
			{
				id.el[t_prev.i].defined = true;
			}
		}

// вычисления
	// если встречается while | id (состояние 30) значит начинается использование переменных
		if(s_prev == 30)
		{
			flag_solving = true;
		}else
	// после } (состояние 9) использование переменных заканчивается
		if(s_prev == 9)
		{
			flag_solving = false;
		}
	// если идет использование переменных и встретилась id то проверяем его атрибут defined (вдруг не описана)
		if(flag_solving && t_prev.table == 4)
		{
			if(!id.el[t_prev.i].defined)
			{
				fprintf(out_errors, "не описана переменная %s\n", get_token_string(t_prev));
				return ERROR_FATAL;
			}
		}
// постфикизация
// тут уже выловлены все ошибки
		
		bool res_simple = state_simple(s_prev);	// обычные
		bool res_begin = state_begin(s_prev);	// начинающие
		bool res_end = state_end(s_prev);		// завершающие
		bool res_dont_write = state_dont_write(s_prev);		// не выводить токен?

		if(res_simple || res_begin || res_end)
		{
			// токен начинающий блок помещаем в стек.
			if(res_begin)
			{
				if(s_prev == 35)		//while
				{
					count_whiles++;
					// портим t_prev
					// сразу выводим метку конца начала цикла
					t_prev.table = WHILE_BEGIN_ID;
					t_prev.i = count_whiles;
					write_token(out, t_prev.table, t_prev.i);
#if defined(DEBUG)
					printf("%s\n", get_token_string(t_prev));
#endif
					// а в стек отправляем метку конца цикла
					t_prev.table = WHILE_END_ID;
					t_prev.i = count_whiles;					
				}
				stack_tokens_head++;
				if(stack_tokens_head >= STACK_TOKENS_LEN)
				{
					if(increace_stack() != 0)	return ERROR_FATAL;
				}
				stack_tokens[stack_tokens_head] = t_prev;
			}else
			// токен завершающий блок. Выводим его, если он не в черном списке, затем выводи токен начинающий блок из стека
			if(res_end)
			{
				if(!res_dont_write)
				{
					write_token(out, t_prev.table, t_prev.i);
#if defined(DEBUG)
					printf("%s\n", get_token_string(t_prev));
#endif
				}
				if(stack_tokens_head < 0) ERR("Критическая ошибка: стек токенов пуст\n", ERROR_FATAL);
				write_token(out, stack_tokens[stack_tokens_head].table, stack_tokens[stack_tokens_head].i);
#if defined(DEBUG)
				printf("%s\n", get_token_string(stack_tokens[stack_tokens_head]));
#endif
				stack_tokens_head--;
			}else
			// рядовой символ требующий отображения
			if(res_simple)
			{
				write_token(out, t_prev.table, t_prev.i);
#if defined(DEBUG)
				printf("%s\n", get_token_string(t_prev));
#endif
			}
		}
	}

end:;
// последним должен быть специальный завершающий токен
	fscanf(tok_in, "%d%d", &t.table, &t.i);
	if(t.table != -1 || t.i != -1)
	{
		ERR("лишний код после конца программы\n", ERROR_FATAL);
	}
	write_token(out, -1, -1);// завершающий токен
	fclose(out);
	fclose(tok_in);
	delete stack;
	delete stack_tokens;
	for(i = 1; i <= tab_size; i++)
	{
		delete tab[i].tok;
	}
	delete tab;
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// ГЕНЕРАТОР КОДА
///////////////////////////////////////////////////////////////////////////////

int make_code(const char *file_name_tree, const char *file_name_listing)
{
	FILE *in, *out;
// стек для хранения токенов
	TOKEN t, t1, t2, temp;
	char s[STRING_LEN*2];
	int i;
	in = fopen(file_name_tree, "r");
	ERR_FILE(in, file_name_tree);
	out = fopen(file_name_listing, "w");
	ERR_FILE(out, file_name_listing);
// заголовок программы
	PUT(".386");
	PUT(".MODEL FLAT");
	PUT(".DATA");
// описание переменных
	for(i = 0; i < id.N; i++)
	{
		if(id.el[i].name != NULL)
		{
			sprintf(s, "_%s DD ?", id.el[i].name);
			PUT(s);
		}
	}
// сегмент кода
	PUT(".CODE");
	PUT("START:");
	for(;;)
	{
		// очередной токен
		fscanf(in, "%d%d", &t.table, &t.i);
		if(t.table == -1 && t.i == -1)
			break;
		else
// идентификатор значит дальше будут арифметические операции
		if(t.table == ID_ID)
		{
			// EAX = первое слагаемое
			fscanf(in, "%d%d", &temp.table, &temp.i);		// id | const
			if(temp.table == ID_ID)
				sprintf(s, "MOV EAX, _%s", get_token_string(temp));
			else
				sprintf(s, "MOV EAX, %s", get_token_string(temp));
			PUT(s);
			for(;;)
			{
				fscanf(in, "%d%d", &t1.table, &t1.i);		// id | const | =
				if(t1.table == OPER_ID && t1.i == 4) break;	//=
				//если не равно
				fscanf(in, "%d%d", &t2.table, &t2.i);		// + | -
				if(t2.table == OPER_ID && t2.i == 0)		// +
				{
					if(t1.table == ID_ID)
						sprintf(s, "ADD EAX, _%s", get_token_string(t1));
					else
						sprintf(s, "ADD EAX, %s", get_token_string(t1));
					PUT(s);
				}
				else										// -
				{
					if(t1.table == ID_ID)
						sprintf(s, "SUB EAX, _%s", get_token_string(t1));
					else
						sprintf(s, "SUB EAX, %s", get_token_string(t1));
					PUT(s);
				}
			}
			// приравниваем t = EAX
			sprintf(s, "MOV _%s, EAX", get_token_string(t));
			PUT(s);
		}else
//  начало цикла
		if(t.table == WHILE_BEGIN_ID)
		{
			// ставим метку
			sprintf(s, "WHILE_START%d:", t.i);
			PUT(s);
			// далее идут 2 операнда и знак операции  сравнения
			fscanf(in, "%d%d", &t1.table, &t1.i);		// id | const
			fscanf(in, "%d%d", &t2.table, &t2.i);		// id | const
			fscanf(in, "%d%d", &temp.table, &temp.i);	// < | > | <= | >=
			if(t1.table == ID_ID)
				sprintf(s, "MOV EAX, _%s:", get_token_string(t1));	// EAX = t1
			else
				sprintf(s, "MOV EAX, %s:", get_token_string(t1));
			PUT(s);
			if(t2.table == ID_ID)
				sprintf(s, "CMP EAX, _%s:", get_token_string(t2));	// (t1=EAX) VS t2
			else
				sprintf(s, "CMP EAX, %s:", get_token_string(t2));
			PUT(s);
			if(temp.i == 2)								// <
			{											
				sprintf(s, "JGE WHILE_END%d", t.i);		// >= - условие выхода из цикла
				PUT(s);
			}else
			if(temp.i == 3)								// <=
			{											
				sprintf(s, "JG WHILE_END%d", t.i);		// > - условие выхода из цикла
				PUT(s);
			}else
			if(temp.i == 5)								// >
			{											
				sprintf(s, "JLE WHILE_END%d", t.i);		// <= - условие выхода из цикла
				PUT(s);
			}else
			if(temp.i == 6)								// >=
			{											
				sprintf(s, "JL WHILE_END%d", t.i);		// < - условие выхода из цикла
				PUT(s);
			}			
		}else
//  конец цикла
		if(t.table == WHILE_END_ID)
		{
			// безусловный переход
			sprintf(s, "JMP WHILE_START%d", t.i);
			PUT(s);
			sprintf(s, "WHILE_END%d:", t.i);
			PUT(s);

		}

	}
	PUT("END START");
	fclose(in);
	fclose(out);
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// ГОЛОВНАЯ ПРОГРАММА
///////////////////////////////////////////////////////////////////////////////

unsigned CALLBACK timer_proc(void*)
{
	int count = 0, c;
    while (true)
    {
        Sleep(1*1000);
		count += 60;
        printf("Текущий этап трансляции: %s. Программа выполняется уже %d минут. Прекратить?Y/N ", PHASE_NAME[PHASE_ID], count/60);
		c = getchar();
		if(c == 'y' || c == 'Y') break;
    }
	fprintf(out_errors, "Процесс трансляции прерван по техническим причинам\n");
	_exit(0);
	return 0;
}

void main()
{
	SetConsoleCP(1251);
	SetConsoleOutputCP(1251);
	HANDLE hThread;
	int R;
	FILE *config;
	keys.el = NULL;
	oper.el = NULL;
	sep.el = NULL;
	id.el = NULL;
	consts.el = NULL;
	stack = NULL;
	stack_tokens = NULL;
	tab = NULL;
	config = fopen("config.txt", "r");
	if(config == NULL)
	{
		STACK_LEN			= 1024;
		STACK_TOKENS_LEN	= 1024;
		TABLE_ID_LEN		= 1024;
		TABLE_CONSTS_LEN	= 1024;
	}
	else
	{
		fscanf(config, "%d%d%d%d", &STACK_LEN, &STACK_TOKENS_LEN, &TABLE_ID_LEN, &TABLE_CONSTS_LEN);
		fclose(config);
	}

	PHASE_ID = 0;
	hThread = (HANDLE)_beginthreadex(NULL, 0, timer_proc, NULL, 0, NULL);
	if(keys.load("keys.txt") == ERROR_FATAL) return;
	if(oper.load("oper.txt") == ERROR_FATAL) return;
	if(sep.load("sep.txt") == ERROR_FATAL) return;
	if(id.init(TABLE_ID_LEN) == ERROR_MEMORY) return;
	if(consts.init(TABLE_CONSTS_LEN) == ERROR_MEMORY) return;
	
	PHASE_ID = 1;
m1:	R = make_tokens("code.cpp", "_tokens.txt");
	if(R == ERROR_FATAL) return; else
	if(R == ERROR_OVERFLOW) {if(increace_table() != 0) return; else goto m1;} else
	if(R == ERROR_MEMORY) return;
	id.save("_id.txt"); id.release();
	consts.save("_consts.txt");	consts.release();
		
	PHASE_ID = 2;
	id.load("_id.txt");
	consts.load("_consts.txt");
	R = make_tree("table.txt", "_tokens.txt", "_tree.txt");
	if(R == ERROR_FATAL) return;
	id.save("_id.txt"); id.release();
	consts.save("_consts.txt");	consts.release();
	
	PHASE_ID = 3;
	id.load("_id.txt");
	consts.load("_consts.txt");
	R = make_code("_tree.txt", "_listing.asm");
	if(R == ERROR_FATAL) return;

	PHASE_ID = 4;
	keys.release();
	oper.release();
	sep.release();
	id.release();
	consts.release();
	CloseHandle(hThread);
}

 

 

  картинка для ясности

MAnsXQo.png

 

jDx9OG2.png

вроду эту лабу ещё не скидывал, хз

 

сделано конечно хуёва, особенно хеш таблица

но эта хуета большего не заслуживала

 

Ты хотя бы todo приложение сможешь сделать, лабер?


 

Жиза для любопытных

Чекнул = пидор

 

Поделиться сообщением


Ссылка на сообщение
Zellar написал 8 часов назад:

todo приложение сделать

в чём проблема?

 

и чё вы доебались, свой код выкладывайте

а то отмазы типа договор нелья кококо

наверняка есть код какойнить которым можно серануть давайте ребзи я хочу посмотреть


:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:    всё что пишу -- шизофренический бред     :zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

Поделиться сообщением


Ссылка на сообщение
(изменено)

Мужики, я так заебался быть проектным манагером, слишком стрессовая хуйня. Думаю в разработку перекатиться.

 

Раньше думал, что фронт это прикольно — люди видят результат твоeй работы и можно всякие свистелки перделки делать. Но сейчас я думаю, что рот ебал фронт, потому что это снова постоянные правки, плотное общение с заказчиком и все то, от чего я хочу сейчас уйти. 

 

В беке как обстоят дела со всем этим? Я хочу как на заводе с 10 до 7 на станке похуячить под лофай хип хоп радио, ровно в 7 нажаль альт ку ку и меня больше ничего не ебет до следующего рабочего дня. Что учить, чтобы условно одну таску дрочить неделями, без постоянного общения с кем-либо? 


Изменено пользователем EnergyFrost
Pep_See, E1azor и GoldRobot понравилось это

Поделиться сообщением


Ссылка на сообщение
E1azor said 42 minutes ago:
Zellar said 8 hours ago:

todo приложение сделать

в чём проблема?

 

и чё вы доебались, свой код выкладывайте

а то отмазы типа договор нелья кококо

наверняка есть код какойнить которым можно серануть давайте ребзи я хочу посмотреть

Я тоже могу тебе лабы с универа покидать, "очень интересные", например скрипт теоремы пифагора, который высчитывает квадрат гипотенузы. Очень бля интересно


 

Жиза для любопытных

Чекнул = пидор

 

Поделиться сообщением


Ссылка на сообщение
EnergyFrost написал 49 минут назад:

Мужики, я так заебался быть проектным манагером, слишком стрессовая хуйня. Думаю в разработку перекатиться.

 

Раньше думал, что фронт это прикольно — люди видят результат твоeй работы и можно всякие свистелки перделки делать. Но сейчас я думаю, что рот ебал фронт, потому что это снова постоянные правки, плотное общение с заказчиком и все то, от чего я хочу сейчас уйти. 

 

В беке как обстоят дела со всем этим? Я хочу как на заводе с 10 до 7 на станке похуячить под лофай хип хоп радио, ровно в 7 нажаль альт ку ку и меня больше ничего не ебет до следующего рабочего дня. Что учить, чтобы условно одну таску дрочить неделями, без постоянного общения с кем-либо? 

 

можно и на фронте с 10 до 19 и альт ку ку, и на бекенде постоянно ебаться со всеми: все зависит от места работы и проекта

лучше тогда английский учи и выкатывайся из рашки, в той же чехии абсолютно все работают так как ты описал

Поделиться сообщением


Ссылка на сообщение
Zellar написал 7 минут назад:
E1azor написал 52 минуты назад:
Zellar написал 8 часов назад:

todo приложение сделать

в чём проблема?

 

и чё вы доебались, свой код выкладывайте

а то отмазы типа договор нелья кококо

наверняка есть код какойнить которым можно серануть давайте ребзи я хочу посмотреть

Я тоже могу тебе лабы с универа покидать, "очень интересные", например скрипт теоремы пифагора, который высчитывает квадрат гипотенузы. Очень бля интересно

это похоже на введение в прогание в школе

интересно чё за вуз если у вас это лаба :pepehands:

 

покидай нормальных лаб где хотя бы 500 строк кода есть

ну ващет я не только лабы кидал, ещё кидал модуль для сплайнов вроде

(старую версию)

 

в чём проблема сделать аналог приложения todo ты так и не ответил


:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:    всё что пишу -- шизофренический бред     :zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

Поделиться сообщением


Ссылка на сообщение
E1azor said 3 minutes ago:
Zellar said 13 minutes ago:
E1azor said 58 minutes ago:
Zellar said 9 hours ago:

todo приложение сделать

в чём проблема?

 

и чё вы доебались, свой код выкладывайте

а то отмазы типа договор нелья кококо

наверняка есть код какойнить которым можно серануть давайте ребзи я хочу посмотреть

Я тоже могу тебе лабы с универа покидать, "очень интересные", например скрипт теоремы пифагора, который высчитывает квадрат гипотенузы. Очень бля интересно

это похоже на введение в прогание в школе

интересно чё за вуз если у вас это лаба :pepehands:

 

покидай нормальных лаб где хотя бы 500 строк кода есть

ну ващет я не только лабы кидал, ещё кидал модуль для сплайнов вроде

(старую версию)

В школе на информатике меня учили как мышкой пользоваться и клавиатурой, и рисовать в paint. А так же, какому то древнему ЯП, где строки кода нужно было самому пронумеровывать
В любом случае, лабы это хуита полнейшая

GoldRobot понравилось это

 

Жиза для любопытных

Чекнул = пидор

 

Поделиться сообщением


Ссылка на сообщение

Ну и накидай своих лаб (нормальных, 500 строк+) хотя бы, в чём проблема? Мне просто интересно.

Или лучше не лаб, если есть возможность.


:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:    всё что пишу -- шизофренический бред     :zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

Поделиться сообщением


Ссылка на сообщение
EnergyFrost said 1 hour ago:

Мужики, я так заебался быть проектным манагером, слишком стрессовая хуйня. Думаю в разработку перекатиться.

 

Раньше думал, что фронт это прикольно — люди видят результат твоeй работы и можно всякие свистелки перделки делать. Но сейчас я думаю, что рот ебал фронт, потому что это снова постоянные правки, плотное общение с заказчиком и все то, от чего я хочу сейчас уйти. 

 

В беке как обстоят дела со всем этим? Я хочу как на заводе с 10 до 7 на станке похуячить под лофай хип хоп радио, ровно в 7 нажаль альт ку ку и меня больше ничего не ебет до следующего рабочего дня. Что учить, чтобы условно одну таску дрочить неделями, без постоянного общения с кем-либо? 

 

Если ты постоянно правки делаешь, значит ТЗ составлял долбаеб, который не смог нормально бизнес требования перевести в функциональные требования


 

Жиза для любопытных

Чекнул = пидор

 

Поделиться сообщением


Ссылка на сообщение

это реально выглядит как спор взрослого со школьником: мерить все в лабах, когда 99,9999999999999% них рассчитаны на закрепление материала даунятами которые только начали что то учить, в то время как взрослые дяди, которые уже давно перешли этот уровень, объясняют этому школьнику что мир не крутится вокруг его любимого визуал бейсика

либо элазор погрузился на такой уровень троллинга что уже выбраться оттуда не может, либо надо по кд давать ему таску "покажи код или 7 дней"

ни один код не может стоить миллионы долларов в руках человека которому не хватает денег на кофе, так что это супер хуевая отмазка

Pep_See и GoldRobot понравилось это

Поделиться сообщением


Ссылка на сообщение
Гость
Эта тема закрыта для публикации сообщений.

×
×
  • Создать...