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:
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 ;)
Czym kompresowales?
"wykonywający"?
ładne ;)
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 ;)
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