powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Анализ исходного кода. Разбор IOCCC 1985 august
25 сообщений из 281, страница 5 из 12
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788793
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Потому что я процент добавил в конце первой маски, и не заметил этого :(
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788821
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вы считаете, такая функция имеет право быть ?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
int test(char* p)
{
	p = (char*)malloc(10);
	for (int i = 0; i < 9; ++i)
	{
		*(p + i) = 'a' + i;
	}
	p[9] = '\0';
	
	printf("%s %i\n", p, strlen(p));
	return 0;
}



Подскажите пожалуйста, как бы вы её вызывали ?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788837
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryКак вы считаете, такая функция имеет право быть ?
право конечно имеет,
но зачем ей игнорируемый параметр и фиксированное возвращаемое значение?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788855
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я хотел делать так:
Код: plaintext
1.
2.
char* p;
test(p);



но не получилось. Интуитивно догадываюсь почему, но чёткого обоснования для себя я не дал.

пришлось возвращать char* и делать так
Код: plaintext
1.
2.
char* p;
p=test(p);
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788900
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryИнтуитивно догадываюсь почему, но чёткого обоснования для себя я не дал.
char** p;


SashaMercury
Код: plaintext
1.
2.
char* p;
p=test(p);


а зачем параметр p нужен?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788911
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропила зачем параметр p нужен?

в принципе, он видимо избыточен. Сейчас исправлю
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788924
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Функция поиска макросов создана, и протестирована в первом приближении.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
//как бы лучше назвать ?
int search_and_set_MacroSpace(FILE* in, struct MacroSpace* ms)
{
	do
	{
		char* w1 = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
		fscanf(in, "%s", w1);
		(strcmp(w1, "#define") == 0) ? add_macros(ms, in) : false;
	} 
	while (step_to_newline(in) != -1);
	return 0;
}



, где

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
//Добавление макроопределиния к пространству макросов
int add_macros(struct MacroSpace* ms, FILE* in)
{
	//1. Работа с памятью 
	ms->count += 1;
	ms->m = (struct Macro*)realloc(ms->m, ms->count*sizeof(struct Macro));
	struct Macro* cur = &(ms->m[ms->count - 1]);//указатель на текущий макрос, создал его чтобы было проще работать в дальнейшем
	setstartvalue_Macro(cur);//инициализация всех элементов текущей(вновь созданной) структуры макроопределения стартовыми значениями

	//2. Инициализация макроопределния

	//иниициализация идентификатора cur->identifier
	skipspaces(in);
	cur->identifier = set_value(in, MASK1);

	//инициализация типа макроимени и массива аргументов cur->list_args
	int next_char = fgetc(in);
	if (next_char == '(')
	{
		cur->type = 1;//меняю тип макроимени
		//инициализация массива аргументов
		int i = 0;
		while ((char)next_char != ')')
		{
			skipspaces(in);
			cur->list_args = (char**)realloc(cur->list_args, (i + 1)*sizeof(char*));
			cur->list_args[i] = NULL;
			cur->list_args[i] = set_value(in, MASK1);

			cur->count_args += 1;
			skipspaces(in);
			fscanf(in, "%c", &next_char);
			i += 1;
		}
	}

	//инициализация  cur->repl_list
	cur->rep_list = set_value(in, MASK2);
	return 0;
}



и

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
char* set_value(FILE* in, const char* mask)
{
	char* buf = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
	fscanf(in, mask, buf);
	int len = strlen(buf) + 1;
	char* res = (char*)malloc(sizeof(char)*len);
	strcpy(res, buf);
	free(buf);
	return res;
}



и ещё две функции,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
//Устанавливает позицию  индикатора файла на первый символ новой строки. Возвращает 1 если всё ок.
//Если файл закончился (новой строки нет), возвращает -1
int step_to_newline(FILE* in)
{
	int c;
	while ((c = getc(in)) != '\n')
	{
		if (c == EOF) return -1;
	}
	return 1;
}

//Пропускает все пробелы
int skipspaces(FILE* in)
{
	int c;
	while ((c = getc(in)) == ' ');
	ungetc(c, in);
	return 0;
}




Хотя я не пришёл к выводу, как лучше(быстрее и безопаснее), считать по строкам, и потом делать их разбор, либо делать так как сейчас сделано.

а вот и точка входа
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
int main(int argc, char** argv)
{
	FILE* in = fopen("august.c", "r");
	struct MacroSpace* ms = create_MacroSpace();
	search_and_set_MacroSpace(in, ms);
	view_MacroSpace(ms);
	
	fclose(in);
	free(ms);
	return 0;
}
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788942
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поиск директив "#define" это лексический анализ, а дальнейший разбор строки макроопределения, это синтаксический анализ. Я так понял. Это правильно ?

В целом функции не слишком поганые ? Или вы бы делали совершенно по-другому ?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788962
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПоиск директив "#define" это лексический анализ, а дальнейший разбор строки макроопределения, это синтаксический анализ. Я так понял. Это правильно ?


нет, кажется, если я правильно понял твою мысль.

В целом, лексер -- это выделение лексем,
парсер (синтаксический анализ) -- грамматик.
Лексемы выделяются безусловно, грамматики -- с вариациями.
Напр. в С это --

Код: plaintext
1.
2.
3.
"Asdfghjk";
12345;
123.456e42;



лексемы, потому что это не может быть ничем другим.

Код: plaintext
1.
a = 25;



уже элемент грамматики, это может быть

Код: plaintext
1.
2.
3.
4.
int 
a = 25;
//or
a = 25;



Что же касается препроцессора, кажется, он не включается в обычную архитектуру компилятора и выполняется отдельно, до него.
Он конечно имеет свой собственный лексер и парсер.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788975
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,
Код: plaintext
1.
(strcmp(w1, "#define") == 0) ? add_macros(ms, in) : false;



Это я считаю форменное безобразие.

надо писать

Код: plaintext
1.
!strcmp(w1, "#define") ? add_macros(ms, in) : false;



Это С, это не паскаль какой-нибудь тебе...

Ну и конечно, тут должен быть IF, ты не вычисляешь выражение, ты ветвишь поток управления.

В С к тому же нет false/true. Традиционно. Что-то там добавляли в последних стандартах -- но настоящий с-шник написал бы

Код: plaintext
1.
!strcmp(w1, "#define") ? add_macros(ms, in) : 0;



И в итоге код должен быть

Код: plaintext
1.
2.
if( !strcmp(w1, "#define") ) 
  add_macros(ms, in);



К тому же между '#' и директивой препроцессора (define в данном случае) могут быть (разрешены) пробелы.

strcmp не покатит, по крайней мере в таком виде.

Думаю, лучше всего всё же использовать регвыражения типа libPCRE.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788980
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
//как бы лучше назвать ?
int search_and_set_MacroSpace(FILE* in, struct MacroSpace* ms)
{
	do
	{
		char* w1 = (char*)malloc(sizeof(char)*MAX_LENGTH_INTERNAL_IDENTIFIER);
		fscanf(in, "%s", w1);
		(strcmp(w1, "#define") == 0) ? add_macros(ms, in) : false;
	} 
	while (step_to_newline(in) != -1);
	return 0;
}




А если strcmp(w1, "#define") , как думаешь, куда девается выделенная память ?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38788987
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Существует #undef, поэтому

Код: plaintext
1.
struct MacroSpace* ms



должен быть стеком, а не просто списком.
Точнее, структура макроопределений должна быть стеком твоих вот этих массивов MacroSpace.
И в каждой точке компиляции кода должен применяться один из элементов этого стека (top, head).
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38789163
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv, спасибо.

По поводу памяти, я неправ. Забыл освободить. По другим замечаниям, мне нужно подумать, прежде чем ответить
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38789781
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryКстати, скорее всего malloc частный случай realloc, и такое в Си встречается, пока не решил как к этому отношусь, хорошо или плохо. С одной стороны нужно помнить больше функций, происходит дублирование, увеличение общего объёма кода (при подключении библиотек), а с другой стороны скорее всего плюсы какие-то есть, просто я их не вижу в силу своей малой грамотности в теории языков программирования
В сях как-раз мало дублирования функционала. Потому как язык создавался
в помощь разработке ядра Unix. И по сути большинство API просто отражают
kernel-API.

А вот если-бы ты полез в библиотеки и фремворки C#/Java - там просто
оторопь берёт от обилия одних и тех-же яиц в анфас и профиль. Одних
XML-ных API существует дюжина.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38790051
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivSashaMercury,
Код: plaintext
1.
(strcmp(w1, "#define") == 0) ? add_macros(ms, in) : false;



Это я считаю форменное безобразие.

надо писать

Код: plaintext
1.
!strcmp(w1, "#define") ? add_macros(ms, in) : false;



Это С, это не паскаль какой-нибудь тебе...

Ну и конечно, тут должен быть IF, ты не вычисляешь выражение, ты ветвишь поток управления.

В С к тому же нет false/true. Традиционно. Что-то там добавляли в последних стандартах -- но настоящий с-шник написал бы

Код: plaintext
1.
!strcmp(w1, "#define") ? add_macros(ms, in) : 0;



И в итоге код должен быть

Код: plaintext
1.
2.
if( !strcmp(w1, "#define") ) 
  add_macros(ms, in);



К тому же между '#' и директивой препроцессора (define в данном случае) могут быть (разрешены) пробелы.

strcmp не покатит, по крайней мере в таком виде.

Думаю, лучше всего всё же использовать регвыражения типа libPCRE.

код исправил, в целом я согласен. Использование тернарного оператора не есть самое удачное решение в данном конкретном случае. Поиск исправлю в дальнейшем, сейчас не хочу отрывать от несколько другой задачи, нужно сделать все замены в файле.
По поводу организации данных, вы правы. Сейчас исправлять не буду, в дальнейшем, возможно, я это учту. Опять таки, пока не хочу отвлекаться от основной задачи.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38790058
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот если бы я для считывания данных использовал посимвольный анализ, а не fscanf (хотя fscanf тоже веротяно читает по символам), было бы быстрее/медленнее ?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38790064
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

fscanf медленнее, чем посимвольное чтение, т.к. ему приходится еще разбирать строку формата при каждом вызове.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38790070
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

это значит, что если бы у вас были знания на уровне моих в области Си(дело в том, что возможно есть другие функции, наиболее оптимальные, или есть библиотека о которой я не знаю, и использование этих функций/библиотек должно быть тут, а не посимвольное fscanf и getc(in)), то вы бы реализовали аналогичный алгоритм формирующий пространство макроимён через посимвольный анализ ?
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38790071
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

Я бы использовал готовый генератор лексических анализаторов вместо самописного лексера. Например flex.
А алгоритм бы уже работал с лексемами.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38790104
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryAnatoly Moskovsky,

это значит, что если бы у вас были знания на уровне моих в области Си(дело в том, что возможно есть другие функции, наиболее оптимальные, или есть библиотека о которой я не знаю, и использование этих функций/библиотек должно быть тут, а не посимвольное fscanf и getc(in)), то вы бы реализовали аналогичный алгоритм формирующий пространство макроимён через посимвольный анализ ?

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

если бы ты знал в деталях, как работает fscanf, ты бы тоже его не использовал.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38791142
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryэто значит, что если бы у вас были знания на уровне моих в области Си(дело в том, что возможно есть другие функции, наиболее оптимальные, или есть библиотека о которой я не знаю, и использование этих функций/библиотек должно быть тут, а не посимвольное fscanf и getc(in)), то вы бы реализовали аналогичный алгоритм формирующий пространство макроимён через посимвольный анализ ?
Вопрос-то как звучит? Наиболее оптимальные! По объёму кода - для данной задачи наверное
fscanf хватит. Лаконично. По скорости.. надо попрофилировать. Дать тыщу исходников. Тогда наверное
fgets, или getc будет быстрее. Но для него надо хорошенький Finite-State-Machine для разбора написать.
И еще критерий можно придумать. Дуракоустойчивость. Возможность exploit-a.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38791247
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton Наиболее оптимальные!
режет глаз словосочетание
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38791291
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилmayton Наиболее оптимальные!
режет глаз словосочетание

не издевайтесь :) Когда пишу, то порой не успеваю за своими мыслями, потому подгоняю себя, тем самым минимизирую время поиска подходящего слова, потому порой пишу неграмотно, или с опечатками. И я не Фёдор Михайлович Достоевский, чтобы изощряться, и не Бальмонт с его "Я изысканность русской медлительной речи ...".
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38791292
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Особенно когда много думаешь прежде чем написать, в голове совсем другие мысли, а не о том как не ошибиться в грамматике/орфографии. Главное передать суть, и ничего не забыть, увеличение риска появления ошибки не играет слишком большой роли на фоне основной задачи. Тем не менее, я считаю, что писать нужно грамотно.
...
Рейтинг: 0 / 0
Анализ исходного кода. Разбор IOCCC 1985 august
    #38791316
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryграмматике/орфографии.
с грамматикой/орфографией проблем нет.
...
Рейтинг: 0 / 0
25 сообщений из 281, страница 5 из 12
Форумы / C++ [игнор отключен] [закрыт для гостей] / Анализ исходного кода. Разбор IOCCC 1985 august
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]