Tarefa:
Você deve criar um intérprete que possa analisar trechos de uma linguagem de programação. A linguagem não precisa ser complexa, mas deve incluir os seguintes elementos sintáticos:
- Capacidade de atribuir e ler variáveis (pode ser tão simples quanto
a
-z
sendo variáveis pré-fabricadas) - Instruções If (elseif e else não são necessárias)
- Loops (contando com um número arbitrário, o acesso do usuário ao contador não é necessário)
- Matemática simples com variáveis (adição, subtração, multiplicação, divisão, maior / menor que, igual a)
- Imprimir declarações
Regras:
- Você não pode copiar a sintaxe de outro idioma popular.
- Você precisa escrever seu próprio intérprete, não a modificação de outro intérprete.
- Você pode escrever seu intérprete em qualquer idioma.
- Escreva um programa de exemplo de 99 garrafas de cerveja no seu idioma (veja aqui )
- Este é um concurso de popularidade , portanto a resposta mais votada vence.
popularity-contest
interpreter
parsing
O médico
fonte
fonte
Respostas:
DogeScript
O programa de 99 garrafas de cerveja:
O intérprete PHP:
A sintaxe como está atualmente:
Experimente aqui .
Todas as sugestões de melhoria são bem-vindas.
fonte
BrainBack: uma linguagem compilada baseada em pilha e rodando no BrainFuck
NB: A especificação foi alterada de "criando um analisador" para "criar um intérprete" depois de postar esta resposta. Esta resposta é um compilador que também analisa o código fonte.
O nome é um trocadilho em Back, sendo o oposto de uma linguagem baseada em pilha bem conhecida e Brain indicando sua natureza esotérica. Parece um pouco com o BrainFuck (embora não seja), mas é compilador executado no BrainFuck e seu código de objeto compilado termina como binários do BrainFuck.
A linguagem: * == destrói seus argumentos
"constant"
imprime constante#
imprime o topo da pilha como número>
duplica o topo da pilha<num>
empurre o número constante<num>
como um valor para o topo da pilha<
remova a parte superior da pilha-
subtexto mais acima do segundo mais alto *+
adicione o topo ao segundo topo *!
não alterna positivo / zero *[ ... ]
faz um tempo no topo da pilha diferente de zero, muito semelhante ao BrainFuck99 garrafas de cerveja com letras corretas no BrainBack:
O compilador BrainBack, escrito em Extended BrainFuck
Para compilar o BrainBack:
Para compilar um programa BrainBack:
Execute o binário:
Aqui eu uso o bf, que está disponível na maioria das distribuições debian.
beef
e outros também podem ser usados. O compilador EBF, BrainBack e seu código de objeto tornam-se binários BrainFuck bastante compatíveis.Provavelmente, deve ser estendido para imprimir uma célula como ascii
.
, ser capaz de ler um byte,
e ter váriasswap
operações para ser mais útil. É absolutamente necessário para criar um compilador ou intérprete no BrainBack.fonte
€
Passo a maior parte do tempo em scripts PHP e isso me fez uma pergunta: por que sou forçado a usar
$
para os nomes das minhas variáveis?€
é minha moeda local, então vamos usá-lo! Como € é usado em muitos países, usei algumas palavras das línguas da UE como palavras-chave.Palavras-chave:
gleich
é igual em alemãomientras
é enquanto em espanholtopo
é maior em português (atualização: em vez disso, deve ser maior , graças a daHugLenny pela dica)odejmowanie
é subtrair em polonêsafficher
é impresso em francêsnl
às vezes, e o TLD deNETHERLANDS
énl
, então eu defini uma constanteNETHERLANDS
para exibir novas linhasEu trapacei um pouco, já que não há
if
palavra-chave, escolhi imprimir diretamente as duas últimas linhas.Intérprete em Python
O intérprete não fará mais do que executar o script para exibir 99 garrafas de cerveja.
Para executá-lo, salve os dois arquivos e execute o arquivo Python com o
.eu
script como argumento:fonte
topo
é o top em português1Lang
1Lang é uma linguagem de prefixo funcional como LISP ou Scheme, mas sem parênteses que dificulta a leitura quando todo o espaço em branco desnecessário é removido. Os parênteses podem ser removidos, pois todas as funções e operadores usam um número conhecido de parâmetros.
As chaves são necessárias para delimitar o corpo da função e conseqüências condicionais e blocos de código alternativos que podem consistir em uma lista de instruções.
No LISP, o fatorial pode ser definido assim:
em 1Lang isso seria
que pode ser reduzido a
Atualmente, o 1Lang não oferece efeitos colaterais.
O 1Lang é escrito em bash e, atualmente, compartilha algumas limitações do bash, como intervalo inteiro.
Nota: as listas não estão totalmente implementadas.
Inteiros são números inteiros de bash (até -2 ^ 32 a 2 ^ 31-1, eu acho). Números negativos não podem ser usados diretamente. Para inserir um negativo, subtraia-o de zero. por exemplo. -5 seria inserido como -0 5. Essa limitação ocorre porque 1Lang é um trabalho em andamento e não foram necessários números negativos para este aplicativo. Estou pensando em usar ~ como um operador negativo unário que permitiria a entrada de -5 como ~ 5.
O espaço em branco é necessário para delinear números inteiros. por exemplo. +2 3
Os nomes dos parâmetros de função podem sobrecarregar as variáveis dos chamadores. Todas as variáveis atribuídas dentro de uma função são locais.
A impressão não é necessária (embora possa ser útil) porque, como LISP, cada instrução retorna um valor e o último valor retornado é impresso.
Um comportamento inesperado da notação de prefixo sem parênteses é que a concatenação de strings pode ser realmente fácil de escrever. Digamos que você queira concatenar
"a" " quick" " brown" " fox"
, pode-se escrever:Mas um método mais legível e menos propenso a erros é o seguinte:
ou
99 garrafas de cerveja código:
A função B retorna "Não há mais garrafas" ou "1 garrafa" ou "garrafas", dependendo de x.
A função F retorna versos normais ou versos finais. Um verso normal é concatenado com o verso seguinte, chamando recursivamente F com -x1. Quando x é 0, F retorna o verso final.
Isso gera (para F5, o significado começa em 5 garrafas de cerveja ...):
1 Intérprete de língua (escrito em bash) em menos de 500 linhas.
fonte
@Mfxy{fxy}M+3 4
funcionasse, mas você precisará ingressar na função e no espaço de nome variável. Demorou um pouco para calcular 99 cervejas: pcons
que pudermap
M\x{*x2}C1C2C3C4/ => (2 4 6 8)
Metade (intérprete / tradutor no Windows Batch)
Não sei por que estou respondendo a tantos quebra-cabeças no lote do Windows, por algum motivo doentio que acho que estou gostando: P De qualquer forma, isso é semelhante a algo em que trabalhei há algum tempo, uma linguagem básica que é traduzido para o lote do windows por um script que também é gravado no lote do windows. Não é particularmente incrível, mas funciona.
99 garrafas de cerveja
Sintaxe
Apenas três tokens são reconhecidos em cada linha, separados por espaços.
# é um comentário.
Na maioria dos casos em que um valor é necessário, a
$
no segundo token significa que o terceiro deve ser tratado como um nome de variável, enquanto a~
denota um valor literal. Instruções gerais tomam o formulário<instruction> [$~] <name>
. A definição de uma variável assume a mesma forma, mas é implementada sempre que não é reconhecida.Comandos definidos:
print
ewrite
ambos escrevem saída, maswrite
não adicionam uma nova linha. Precisa de $ ou ~.mark
cria um ponto que pode ser saltado ou chamado como uma sub-rotina.jump
equivalente a ir para lote (ou qualquer outro idioma).proc
chama uma sub-rotina. Equivalente acall :label
.return
retorna de uma sub-rotina. Sairá do programa quando não estiver dentro de um.if
instrução condicional. Leva a comparação da próxima linha, no formulário<var1> <operator> <var2>
. Operadores são os mesmos queif
aos do lote, ou seja.EQU, NEQ, LSS, LEQ, GTR, GEQ
. Só executará instruções depois se a comparação for verdadeira.endif
termina uma instrução if.cat
concatena duas variáveis.cat a b
irá armazenar o valor de ab em a.Quando nenhum desses comandos é encontrado, a expressão é tratada como uma atribuição de variável, usando o primeiro token como o nome da variável.
$
e~
se comportam da mesma forma que emprint
, mas também há um@
identificador. Trata o último token como uma expressão matemática, passada paraset /a
. Inclui a maioria dos operadores. Se nenhum dos três identificadores for encontrado, esse é um erro de sintaxe e o intérprete sai.Intérprete (Lote do Windows)
Na verdade, o intérprete converte o código em lote do Windows, o coloca em um arquivo temporário e o executa. Embora reconheça erros de sintaxe no meio idioma, o script em lote resultante pode causar problemas, especialmente com caracteres especiais como parênteses, barras verticais etc.
fonte
Flex Bison
Atribua variável, se houver outra condição, bloco e alguma outra adição, operação de subtração.
Arquivo laxico
lex.l
Arquivo analisador
com.y
Compilar
Corre
compilador in.txt ou.txt
Arquivo de entrada
a = 3 + (4 * 7) -9; imprima um; c = a + 45; imprimir c;
** Este é o comentário save c;
** salve c no arquivo print c * (a + 32);
Arquivo de saída 67
fonte
Intérprete
Para obter instruções sobre como executar esse código, dê uma olhada na minha outra resposta: /codegolf//a/19935/13186
99 garrafas de cerveja
O programa
fonte
99ISC
O 99ISC usa uma memória orientada para números inteiros de tamanho arbitrário. A memória é indexada por um número inteiro não negativo. Todos os valores na memória são inicializados com seus endereços. Por exemplo. No tempo de execução, o endereço 0 contém o valor 0 e o endereço 9 contém o valor 9.
O 99ISC tem duas instruções. O primeiro imprime a rotina das 99 garrafas de cerveja na parede. Sua sintaxe é uma única linha, como abaixo. A execução continua com a próxima linha do programa.
A segunda instrução é uma instrução "subtrair e ramificar se não for igual a zero". Sua sintaxe é uma única linha, como abaixo.
x
é o endereço do número a ser operado,y
é o endereço do número que está sendo subtraído ez
é a próxima linha a ser executada se o resultado da subtração não for zero. Caso contrário, a execução continuará com a próxima linha.A presença da instrução "subtrair e ramificar se não for zero" torna o 99ISC um OISC (One Instruction Set Computer) e, portanto, Turing completo.
Aqui está um programa que apaga os 10 primeiros valores na memória e imprime a rotina 99 Garrafas de cerveja na parede.
E aqui está um intérprete 99ISC, em Python.
fonte
Eu lhe dou:
Intérprete de pequenos conjuntos de instruções (SISI)
A sintaxe baseia-se em BASIC e assembly. Tem quatro declarações:
set
,print
,jump
(Goto incondicional) ejumpif
(ir para condicional). Toda declaração deve ser precedida por um número de linha. Os tipos de dados suportados são números inteiros e seqüências de caracteres.O próprio intérprete pode ser encontrado no Python 3 no Github (sisi.py). O programa 99 Bottles of Beer também está lá, mas vou reproduzi-lo aqui:
fonte
Pogo
https://github.com/nrubin29/Pogo
fonte
i
e o defino como 99. Então, enquanto i for maior que 0, imprimoi bottles of beer on the wall
e subtraí um dei
. Se o problema é que falta algumas letras, posso adicionar mais.