Program poliglot

Un program poliglot ( poliglot = multilingv) este un program de calculator al cărui cod sursă este valid în mai multe limbaje de programare ; d. Cu alte cuvinte, interpretul sau compilatorul respectiv poate executa sau traduce oricare dintre limbile prevăzute pentru acesta fără erori. De obicei, produce aceeași ieșire atunci când este rulată în limbi diferite . Un astfel de program nu are niciun folos pentru publicul larg, crearea acestuia este doar un exercițiu solicitant pentru programator .

funcționalitate

Deși poate fi aproape imposibil să se formuleze un text poliglot în limbaj natural, crearea unui program poliglot este mai puțin dificilă decât apare inițial. Următoarele fapte și metode sunt utilizate pentru a dezvolta programe poliglote:

  • Părți din cod pot fi valabile în mai multe limbaje de programare, de ex. B. " printf ("...")" generează ieșiri textuale atât în Perl, cât și în C.
  • Comenzile Jump pot fi folosite pentru a sări părțile din textul sursă care sunt nevalide în limba respectivă sau pentru a exittermina execuția programului cu „în timp util” înainte de a apărea coduri nevalide.
  • O linie de program poate reprezenta cod executabil într-un limbaj de programare și un comentariu în celălalt . De exemplu, „ # include ...” în C este o instrucțiune pre-procesor , în multe limbaje de scriptare - datorită caracterului „ #” de la începutul liniei - o linie de comentariu.
  • În unele limbaje de programare (de exemplu, în C cu o instrucțiune preprocesor) puteți redefini jetoanele sau redefini cele existente și astfel puteți face un jeton valabil într-un limbaj de programare străin valabil și în propriul dvs. - posibil cu un sens diferit.

Un exemplu simplu

Următorul exemplu este mult mai puțin spectaculos decât cel la care se face referire în linkurile web; a fost special conceput cu scopul de a face mai ușor de înțeles, chiar și pentru profan. Se folosește de primele trei dintre tehnicile menționate mai sus.

Cod sursa Explicaţie

# include <stdio.h> /*                  
eval "echo 'Hello, world!'; exit";
sub echo { print "@_\n" }; __END__ */
main() { printf ("Hello, world!\n"); }

Codul sursă opus este valid în C, Perl și multe shell-uri Unix (Bourne Shell, Korn Shell , Bash, C Shell, Z Shell). Programul afișează textul „ Bună ziua, lume! „afară.

# include <stdio.h> /*
eval "echo 'Hello, world!'; exit";
sub echo { print "@_\n" }; __END__ */
main() { printf ("Hello, world!\n"); }

C Textul atașat
de /*și */(aici colorat în verde) este un comentariu în C și este ignorat. Restul este o variantă a programului Hello World în C .

# include <stdio.h> /*
eval "echo 'Hello, world!'; exit";
sub echo { print "@_\n" }; __END__ */
main() { printf ("Hello, world!\n"); }

Unix shells
Prima linie (verde) este o linie de comentarii și este ignorată. Când evaldeclarația a fost executată, programul se încheie din cauza exit; restul (gri) nu mai este citit de interpret și, prin urmare, nu este verificat pentru sintaxă corectă .

# include <stdio.h> /*
eval "echo 'Hello, world!'; exit";
sub echo { print "@_\n" }; __END__ */
main() { printf ("Hello, world!\n"); }

Perl
Prima linie este comentariul. Instrucțiunea evaleste executată numai după ce subrutina a fost echo definită în linia 3 . Restul (gri) urmând cuvântul cheie __END__ este citit de către interpret Perl, dar ignorat.

Un exemplu mai complex

Următorul cod sursă este valid în C, PHP și Bash. Sunt utilizate toate metodele descrise mai sus; în special, noua sau redefinirea șirurilor de caractere este necesară într-un număr de cazuri pentru compatibilitatea cu C. Acestea au loc în #definerândurile care încep cu „ ”, care sunt linii de comentarii pentru cele două limbaje de scriptare.

#define a /*
#<?php
echo "\010Hello, world!\n"// 2> /dev/null > /dev/null \ ;
// 2> /dev/null; x=a;
$x=5 // 2> /dev/null \ ;
if (($x))
// 2> /dev/null; then
return 0;
// 2> /dev/null; fi
#define e ?>
#define b */
#include <stdio.h>
#define main() int main()
#define printf printf(
#define true )
#define function
function main()
{
printf "Hello, world!\n"true/* 2> /dev/null | grep -v true*/;
return 0;
}
#define c /*
main
#*/

MS-DOS și Perl

Salut Lume!

Următorul program poate fi executat prin interpretul Perl sau ca fișier DOS - batch . (Explicații pentru fiecare linie din dreapta textului sursă.)

Cod sursa DOS Perla
@rem = '
@echo Hello, world!
@goto END
';
print substr "@rem", 7, 13;
__END__
: END
Kommentar
Ausgabe
Sprung ans Ende
wird übersprungen
wird übersprungen
wird übersprungen
Ende Code
Definition des Arrays @rem
Inhalt des Arrays @rem
Inhalt des Arrays @rem
Ende der Definition von @rem
Ausgabe Teilstring aus @rem
Ende Code
wird ignoriert

Împachetare DOS pentru Perl

Un fișier batch DOS pentru apelarea unui program Perl poate fi creat în mod similar: fișierul batch DOS conține codul Perl și se execută singur (în linia 10) cu interpretul Perl. Cu toate acestea, este nevoie de un efort pentru a colecta argumentele din linia de comandă și a le transmite către Perl:

@rem = ' ---------- BEGIN DOS ------------------
    @echo off
    set PROG=%0.bat
    : ARG LOOP
        if "%1" == "" goto EXEC
        set ARGS=%ARGS% %1
        shift
        goto ARG LOOP
    : EXEC
    perl %PROG% %ARGS%
    goto END
';
# ================ BEGIN PERL ==================

print "Perl here with these arguments: @ARGV\n";

__END__ # ========= END PERL ===================
: END
set PROG=
set ARGS=
:: ---------------- END DOS --------------------

Vezi si

Alte exemple de programe inutile, dar educaționale:

Link-uri web

(Toate sursele citate aici sunt în engleză.)