Programa poliglota

Um programa poliglota ( poliglota = multilíngue) é um programa de computador cujo código-fonte é válido em mais de uma linguagem de programação ; d. Em outras palavras, o respectivo intérprete ou compilador pode executar ou traduzir qualquer uma das linguagens fornecidas para ele sem erros. Geralmente, ele produz a mesma saída quando executado em idiomas diferentes . Tal programa não tem utilidade para o público em geral, sua criação é apenas um exercício exigente para o programador .

funcionalidade

Embora seja quase impossível formular um texto poliglota em linguagem natural, criar um programa poliglota é menos difícil do que parece inicialmente. Os seguintes fatos e métodos são usados ​​para desenvolver programas poliglotas:

  • Partes do código podem ser válidas em várias linguagens de programação, por exemplo, B. " printf ("...")" gera saída textual em Perl e C.
  • Os comandos de salto podem ser usados ​​para pular as partes do texto-fonte que são inválidas no respectivo idioma ou para exitencerrar a execução do programa com “em tempo” antes que códigos inválidos apareçam.
  • Uma linha de programa pode representar código executável em uma linguagem de programação e um comentário em outra . Por exemplo, “ # include ...” em C é uma instrução de pré - processador , em muitas linguagens de script - por causa do caractere “ #” no início da linha - uma linha de comentário.
  • Em algumas linguagens de programação (por exemplo, em C com uma instrução de pré-processador), você pode redefinir tokens ou redefinir os existentes e, assim, tornar um token válido em uma linguagem de programação estrangeira também válido em sua própria - possivelmente com um significado diferente.

Um exemplo simples

O exemplo a seguir é muito menos espetacular do que aquele referenciado nos links da web; foi especialmente elaborado com o objetivo de facilitar a compreensão, mesmo para o leigo. Ele faz uso das três primeiras técnicas mencionadas acima.

Código fonte Explicação

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

O código-fonte ao lado é válido em C, Perl e muitos shells Unix (Bourne Shell, Korn Shell , Bash, C Shell, Z Shell). O programa produz o texto “ Olá, mundo! " Fora.

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

C
O texto entre /*e */(aqui colorido de verde) é um comentário em C e é ignorado. O resto é uma variante do programa Olá Mundo em C .

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

Shells Unix
A primeira linha (verde) é uma linha de comentário e é ignorada. Quando a evalinstrução for executada, o programa será encerrado devido ao exit; o resto (cinza) não é mais lido pelo interpretador e, portanto, não é verificado quanto à sintaxe correta .

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

Perl
A primeira linha é um comentário. A evalinstrução só é executada após a sub-rotina ter sido echo definida na linha 3 . O resto (cinza) após a palavra __END__ - chave é lido pelo interpretador Perl, mas é ignorado.

Um exemplo mais complexo

O seguinte código-fonte é válido em C, PHP e Bash. Todos os métodos descritos acima são usados; em particular, a nova ou redefinição de cadeias de caracteres é necessária em vários casos para compatibilidade com C. Elas ocorrem nas #definelinhas que começam com " ", que são linhas de comentários para as duas linguagens de script.

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

Olá Mundo!

O seguinte programa pode através do intérprete Perl ou como um DOS - arquivo de lote para executar. (Explicações para cada linha à direita do texto fonte.)

Código fonte DOS Pérola
@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

Wrapper DOS para Perl

Um arquivo em lote do DOS para chamar um programa Perl pode ser criado de maneira semelhante: O arquivo em lote do DOS contém o código Perl e é executado (na linha 10) com o interpretador Perl. No entanto, é preciso algum esforço para coletar os argumentos da linha de comando e passá-los para 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 --------------------

Veja também

Outros exemplos de programas inúteis, mas educacionais:

Links da web

(Todas as fontes citadas aqui estão em inglês.)