pecet jogger

cokolwiek o czymkolwiek

Kompilator C napisany w PHP*

08/02/2009, 15:18:26 | 6 komentarzy | Programowanie

Przeglądając wczoraj otchłanie internetu, trafiłem na ciekawą stronę, z pozornie banalnie prostymi zadaniami programistycznymi o nazwie anarchy golf. Znalazłem tam ciekawe zadanie w którym należy napisać program (niby)kompilujący i wykonywający podany kod C.

Oczywiście większość zadań tam dostępnych można rozwiązać oszukując, np. porównując input który otrzymujemy od strony sprawdzającej, i wysyłając odpowiednią odpowiedź, jednak stwierdziłem że byłoby to zbyt proste, dlatego postanowiłem podejść do tego zadania trochę inaczej. W PHP dostępna jest jakże ciekawa funkcja o nazwie eval, która w zasadzie uruchamia zagnieżdżony interpreter PHP i interpretuje podany kod. Poneważ składnia języka PHP jest bardzo podobna do C, gdyż jak wiadomo jest wzorowana na tym języku, postanowiłem stworzyć proste regexy, które "skonwertują" kod C do kodu PHP, który to kod wykonam za pomocą instrukcji eval. W końcu udało mi się uzyskać taki efekt:

anarchy golf

Niestety jest to największy program, i zarazem najgorszy, zapewne da się jakoś zoptymalizować go, zwłaszcza pisząc bardziej wydajne regexy, natomiast sam daje sobie spokój, gdyby ktoś chciał skorzystać z mojego kodu wysyłając własne rozwiązanie do anarchy golf, oczywiście się nie obrażę.

Kod programu po kompresji:

 
<? $z=file_get_contents('php://stdin');$x[]='/(?:void|int|char|long|float|double) ([[:alnum:]_]*)(\(.*?\))/';$y[]='function $1$2';$x[]='/(?:void|int|char|long|float|double)[[:blank:]]/';$y[]='';$x[]='%([[:alnum:]_]+)[[:blank:]]*(\%|/|\*|=|<|>|==|!=|-|\+|\+\+|--|\*=|\+=|-=|/=)[[:blank:]]*(.*?)%';$y[]='\$$1$2$3';$x[]='%(\$[[:alnum:]_]+)[[:blank:]]*(\%|/|\*|=|<|>|==|!=|-|\+|\+\+|--|\*=|\+=|-=|/=)[[:blank:]]*([[:alnum:]_]+)%';$y[]='$1$2\$$3';$x[]='%\(([[:alnum:]_]+)[[:blank:]]*(=|<|>|==|!=|-|\+|\+\+|--|\*=|\+=|-=|/=)[[:blank:]]*(.*?)\)%';$y[]='($$1$2$3)';$x[]='/,([[:blank:]]*)([[:alnum:]_]+)/';$y[]=',$1\$$2';$x[]='/\(([[:alnum:]_]+)/';$y[]='(\$$1';$x[]='/\$([0-9]+)/';$y[]='$1';$z=preg_replace($x,$y,$z)."\nmain();";print"Compiling...\n";print"Running...\n";eval($z); ?>
 

I przed kompresją w razie jakby ktoś chciał coś zrozumieć - dostępny tu.

* - no prawie kompilator ;)

Chris Trynkiewicz (#) 08/02/2009 - 17:59:44

Czym kompresowales?

rozie (#) 08/02/2009 - 18:37:13

"wykonywający"?

D4rky (#) 08/02/2009 - 20:24:14

ładne ;)

pecet (#) 08/02/2009 - 21:22:23

Chris -- ręcznie - usuwałem odstępy i zmieniłem odpowiednie nazwy zmiennych, natomiast na początku wolałem pisać tak żebym sam wiedział o co chodzi w kodzie ;)

Chris Trynkiewicz (#) 09/02/2009 - 00:40:10

Hehe to pozwolisz ze uzyje tego kompresora przy swoich projektach? :D

dzieciak (#) 14/05/2009 - 19:14:17

// license: pecet-eula which is based on Microsoft (R) EULA (TM), whatever its means
it means/ it's meaning... uhhh
:D
jestem tylko głupim dzieciakiem

Dodaj komentarz