Polyglot programma

Een polyglot programma ( polyglot = meertalig) is een computerprogramma waarvan de broncode geldig is in meer dan één programmeertaal ; d. Met andere woorden, de respectieve tolk of compiler kan elk van de talen die ervoor worden geleverd zonder fouten uitvoeren of vertalen. Het produceert meestal dezelfde uitvoer als het in verschillende talen wordt uitgevoerd . Zo'n programma heeft geen nut voor het grote publiek, het creëren ervan is slechts een veeleisende oefening voor de programmeur .

functionaliteit

Hoewel het bijna onmogelijk kan zijn om een ​​meertalige tekst in natuurlijke taal te formuleren, is het maken van een meertalig programma minder moeilijk dan het in eerste instantie lijkt. De volgende feiten en methoden worden gebruikt om polyglot-programma's te ontwikkelen:

  • Delen van de code kunnen geldig zijn in verschillende programmeertalen, bijv. B. " printf ("...")" genereert tekstuele output in zowel Perl als C.
  • Sprongcommando's kunnen worden gebruikt om de delen van de brontekst die ongeldig zijn in de betreffende taal over te slaan of om de uitvoering van het programma exit"op tijd" te beëindigen voordat ongeldige codes verschijnen.
  • Een programmalijn kan uitvoerbare code vertegenwoordigen in de ene programmeertaal en een commentaar in de andere . Bijvoorbeeld: " # include ..." in C is een preprocessorinstructie , in veel scripttalen - vanwege het teken " #" aan het begin van de regel - een commentaarregel.
  • In sommige programmeertalen (bijvoorbeeld in C met een preprocessorinstructie) kun je tokens opnieuw definiëren of bestaande herdefiniëren en zo een token dat geldig is in een vreemde programmeertaal ook geldig maken in je eigen taal - mogelijk met een andere betekenis.

Een simpel voorbeeld

Het volgende voorbeeld is veel minder spectaculair dan het voorbeeld waarnaar wordt verwezen in de weblinks; het is speciaal ontworpen om het begrijpelijker te maken, zelfs voor de leek. Het maakt gebruik van de eerste drie van de hierboven genoemde technieken.

Broncode Uitleg

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

De tegenoverliggende broncode is geldig in C, Perl en veel Unix-shells (Bourne Shell, Korn Shell , Bash, C Shell, Z Shell). Het programma geeft de tekst " Hallo, wereld! "uit.

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

C
De tekst tussen /*en */(hier groen gekleurd) is een opmerking in C en wordt genegeerd. De rest is een variant van de Hello World-programma in C .

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

Unix-shells
De eerste regel (groen) is een commentaarregel en wordt genegeerd. Wanneer de evalinstructie is uitgevoerd, wordt het programma beëindigd vanwege de exit; de rest (grijs) wordt niet meer ingelezen door de tolk en wordt dus niet gecontroleerd op correcte syntaxis .

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

Perl
De eerste regel is commentaar. De evalinstructie wordt pas uitgevoerd nadat de subroutine is echo gedefinieerd in regel 3 . De rest (grijs) na het trefwoord __END__ wordt gelezen door de Perl-interpreter, maar genegeerd.

Een complexer voorbeeld

De volgende broncode is geldig in C, PHP en Bash. Alle hierboven beschreven methoden worden gebruikt; in het bijzonder is de nieuwe of herdefinitie van tekenreeksen in een aantal gevallen nodig voor compatibiliteit met C. Deze vinden plaats in de #defineregels die beginnen met " ", dit zijn commentaarregels voor de twee scripttalen.

#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 en Perl

Hallo Wereld!

Het volgende programma kan via de Perl-interpreter of als een DOS - batchbestand worden uitgevoerd. (Uitleg voor elke regel rechts van de brontekst.)

Broncode DOS Parel
@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

DOS-wrapper voor Perl

Een DOS-batchbestand voor het aanroepen van een Perl-programma kan op een vergelijkbare manier worden gemaakt: Het DOS-batchbestand bevat de Perl-code en voert zichzelf uit (in regel 10) met de Perl-interpreter. Het kost echter enige moeite om de opdrachtregelargumenten te verzamelen en deze door te geven aan 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 --------------------

Zie ook

Andere voorbeelden van nutteloze maar educatieve programma's:

web links

(Alle hier geciteerde bronnen zijn in het Engels.)