Анализ исходного кода. Разбор IOCCC 1985 august

SashaMercury
Дата: 13.08.2014 03:46:24
Здравствуйте.

Вчера я решил заняться чем-нибудь интересным. Решил разобрать код автора august, созданный в 1985 году для IOCCC. Ниже привожу код:
#define p struct c
#define q struct b
#define h a->a
#define i a->b
#define e i->c
#define o a=(*b->a)(b->b,b->c)
#define s return a;}q*
#define n (d,b)p*b;{q*a;p*c;
#define z(t)(t*)malloc(sizeof(t))
q{int a;p{q*(*a)();int b;p*c;}*b;};q*u n a=z(q);h=d;i=z(p);i->a=u;i->b=d+1;s
v n c=b;do o,b=i;while(!(h%d));i=c;i->a=v;i->b=d;e=b;s
w n o;c=i;i=b;i->a=w;e=z(p);e->a=v;e->b=h;e->c=c;s
t n for(;;)o,main(-h),b=i;}main(b){p*a;if(b>0)a=z(p),h=w,a->c=z(p),a->c->a=u,
a->c->b=2,t(0,a);putchar(b?main(b/2),-b%2+'0':10);} 


0.1 Когда я стал его разбирать (на листочке конечно-же), мне стало понять почему мне говорили про кучу define, когда я спрашивал про то, как можно написать работу с длинными числами за 200 символов. Вероятно, написать и правда можно(если обладать фантазией с немалым коэффициентом извращённости).
0.2 Разобрал 2 строки после списка макрозамен, и решил что не серьёзно изучать Си, и не написать для этого программу (тем более, в дальнейшем её можно будет использовать для парсера языка).


1. Я решил, что сначала мне нужно получить список всех замен (как бы это слово правильно назвать, макроподстановок? ) в тексте. Написал для этого алгоритм. Подскажите пожалуйста, верен ли он ? Или я что-то/много что упустил.
2. Вероятно, лучше всего хранить список макрозамен в массиве структур. И ещё должна быть переменная, в которой хранится количество записей. Глобальная переменная.

struct mr
{
	unsigned i;//номер по порядку, хотя я не уверен в его необходимости
	char* identifier = NULL;
	char* replacement_list = NULL;
};
...

struct mr* mrl = NULL;


Хотя в этом я не уверен. Правильно ли я думаю ?

3. Согласно стандарту может быть максимум 4095 разных макроидентификаторов?

ISO/IEC 9899:201x
4095 macro identifiers simultaneously defined in one preprocessing translation unit


4. Можно ли посмотреть код, полученный после работы препроцессора VS ?

Модератор: Вложение удалено.
SashaMercury
Дата: 13.08.2014 03:49:33
Рисунок просто огромный, прошу прощение. Я загружу новый. Удалите пожалуйста старый.
Anatoly Moskovsky
Дата: 13.08.2014 03:54:40
SashaMercury
4. Можно ли посмотреть код, полученный после работы препроцессора VS ?

http://stackoverflow.com/questions/277258/c-c-source-file-after-preprocessing

Вам пора научиться гуглить

ЗЫ. Остальное мне не интересно, поэтому не комментирую.
Dimitry Sibiryakov
Дата: 13.08.2014 11:27:02

Anatoly Moskovsky
Вам пора научиться гуглить

Да хотя бы открыть для себя ключи /?, -h, --help (в зависимости от компилятора)...

Posted via ActualForum NNTP Server 1.5

SashaMercury
Дата: 13.08.2014 13:06:53
Алгоритм не совсем верный, он не распознает функции
mayton
Дата: 13.08.2014 16:26:43
SashaMercury, Сашок. У некоторых компилляторов есть опции
которые показывают результат макро-процессинга.

Воспользуйся им. Потом отформатируй нормально исходник
и мы с удовольствием на него посмотрим.
White Owl
Дата: 13.08.2014 18:07:10
SashaMercury,

Следующий шаг - изучить что такое CFG и bison.
SashaMercury
Дата: 14.08.2014 07:24:31
mayton, спасибо :)

воспользовался ещё вчера, но у меня есть чувство, что навряд-ли вы посмотрите на этот код с удовольствием. Хотя мне он кажется интересным.

#include <stdio.h>
#include <stdlib.h>

struct b
{ 
	int a; 
	struct c
	{ 
		struct b*(*a)(); 
		int b; 
		struct c*c; 
	}*b; 
}; 

struct b* u(int d, struct c* b)
{
	struct b* a; 
	struct c* c; 
	a = (struct b*)malloc(sizeof(struct b)); 
	a->a = d; 
	a->b = (struct c*)malloc(sizeof(struct c)); 
	a->b->a = u; 
	a->b->b = d + 1;
	return a; 
}

struct b* v(int d, struct c* b)
{
	struct b* a; 
	struct c*c; 
	c = b; 
	do a = (*b->a)(b->b, b->c), b = a->b; 
	while (!(a->a%d)); 
	
	a->b = c; 
	a->b->a = v; 
	a->b->b = d; 
	a->b->c = b; 
	return a; 
} 

struct b* w(int d, struct c* b)
{
	struct b* a; 
	struct c* c; 
	a = (*b->a)(b->b, b->c); 
	c = a->b; 
	a->b = b; 
	a->b->a = w; 
	a->b->c = (struct c*)malloc(sizeof(struct c)); 
	a->b->c->a = v; 
	a->b->c->b = a->a; 
	a->b->c->c = c; 
	return a; 
}

struct b* t(int d, struct c* b) 
{ 
	struct b*a; 
	struct c*c; 
	for (;;)
		a = (*b->a)(b->b, b->c), main(-a->a), b = a->b; 
}

main(int b)
{
	struct c*a; 
	if (b>0)a = (struct c*)malloc(sizeof(struct c)), a->a = w, a->c = (struct c*)malloc(sizeof(struct c)), a->c->a = u,
		a->c->b = 2, t(0, a); 
	putchar(b ? main(b / 2), -b % 2 + '0' : 10);
}


Anatoly Moskovsky, я не догадался сделать запрос на английском. Спасибо
mayton
Дата: 14.08.2014 14:30:56
SashaMercury, Саш. Это всё замечательно. А каково назначение этого алгоритма?
SashaMercury
Дата: 14.08.2014 14:34:38
Который я рисовал выше ? Xочу для начала написать слабую версию препроцессора, и алгоритм выше собирает все макроподстановки в файле. Но он не до конца верный