Tornar meu pseudocódigo real

8

Eu tenho um pseudocódigo Java que usa espaço em branco em vez de chaves, e quero que você o converta.

I / O

Seu programa deve levar um arquivo de entrada junto com um número designando quantos espaços são usados ​​para recuar um bloco. Aqui está um exemplo:

$ convert.lang input.p 4
// Converter usando 4 espaços como delimitador de bloco
$ convert.lang input.p 2
// Converter usando 2 espaços como o delimitador de bloco

Em seguida, ele deve converter o resultado usando o delimitador de bloco especificado e enviar o resultado para stdout.

A carne do programa

Os blocos são abertos :e cada linha dentro do bloco é recuada usando o delimitador de blocos, como o código Python.

while (verdadeiro):
    System.out.println ("Teste");

Cada um :está substituído com um {, e uma }é anexado ao fim do bloco.

while (true) {
    System.out.println ("Teste");
}

Exemplos

Entrada:

Teste de classe pública:
    main public void estático (String [] args):
        System.out.println ("Java é detalhado ...");

Resultado:

$ convert Test.pseudojava 4
Teste de classe pública {
    public static void main (String [] args) {
        System.out.println ("Java é detalhado ...");
    }
}

Entrada:

a Principal():
  printf ("Olá Mundo");

Resultado:

$ convert test.file 2
a Principal() {
  printf ("Olá Mundo");
}

Entrada:

def generic_op (the_stack, func):
    # Código genérico de manipulação de operações
    b = the_stack.pop ()
    se isinstance (b, list):
        se b:
            Retorna
        top = b.pop (0)
        enquanto b:
            top = func (parte superior, b.pop (0))
        the_stack.push (superior)
    outro:
        a = the_stack.pop ()
        retornar func (a, b)

Resultado:

$ convert code.py 4
def generic_op (the_stack, func) {
    # Código genérico de manipulação de operações
    b = the_stack.pop ()
    if isinstance (b, list) {
        se b {
            Retorna
        }
        top = b.pop (0)
        enquanto b {
            top = func (parte superior, b.pop (0))
        }
        the_stack.push (superior)
    }
    outro {
        a = the_stack.pop ()
        retornar func (a, b)
    }
}

Pontuação

O código com a menor quantidade de bytes vence!

Estágio
fonte
1
Podemos assumir que a entrada não contém comentários?
Martin Ender
1
@ MartinBüttner Pode conter comentários, mas os comentários não conterão ':'. Basicamente sim.
fase
3
E os rótulos, que são o motivo usual de uma linha terminar em dois pontos na origem Java válida?
Peter Taylor
1
Eu nunca vi um rótulo em lugar algum, exceto no começo de uma linha.
SuperJedi224
2
Acabei de me lembrar de quanto odeio Java.
lirtosiast

Respostas:

5

Perl, 41 bytes

#!perl -p0
1while s/( *).*\K:((
\1 .*)+)/ {\2
\1}/

Contando o shebang como dois, a entrada é retirada de stdin. Um argumento de linha de comando não precisa ser fornecido. Qualquer contexto de aninhamento válido pode ser determinado (e correspondido) sem conhecer o tamanho do recuo.


Divisão Regex

( *)                   # as many spaces as possible (\1)
    .*                 # as many non-newline characters as possible \
                         (greediness ensures this will always match a full line)
      \K               # keep all that (i.e. look-behind assertion)
        :              # colon at eol (newline must be matched next)
         (
          (
           \n\1        # newline with at least one more space than the first match
                .*     # non-newlines until eol
                  )+   # as many of these lines as possible
                    )  # grouping (\2)

Uso da amostra

in1.dat

public class Test:
    public static void main(String[] args):
        System.out.println("Java is verbose...");

Resultado

$ perl py2java.pl < in1.dat
public class Test {
    public static void main(String[] args) {
        System.out.println("Java is verbose...");
    }
}

in2.dat

main():
  printf("Hello World");

Resultado

$ perl py2java.pl < in2.dat
main() {
  printf("Hello World");
}

in3.dat

def generic_op(the_stack, func):
    # Generic op handling code
    b = the_stack.pop()
    if isinstance(b, list):
        if b:
            return
        top = b.pop(0)
        while b:
            top = func(top, b.pop(0))
        the_stack.push(top)
    else:
        a = the_stack.pop()
        return func(a, b)

Resultado

$ perl py2java.pl < in3.dat
def generic_op(the_stack, func) {
    # Generic op handling code
    b = the_stack.pop()
    if isinstance(b, list) {
        if b {
            return
        }
        top = b.pop(0)
        while b {
            top = func(top, b.pop(0))
        }
        the_stack.push(top)
    }
    else {
        a = the_stack.pop()
        return func(a, b)
    }
}
primo
fonte
Eu só escrevi este em ruby
Não que Charles
2

Python 3, 299 265 bytes

import sys;s=int(sys.argv[2]);t="";b=0
for l in open(sys.argv[1]):
 h=l;g=0
 for c in l:
  if c!=" ":break
  g+=1
 if g/s<b:h=" "*g+"}\n"+h;b-=1
 if l.strip().endswith(":"):h=l.split(":")[0];h+=" {";b+=1
 t+=h+"\n"
b-=1
while b>-1:
 t+=" "*(b*s)+"}\n"b-=1
print(t)

Bam bam pow.

Algoritmo usado:

// vars globais
total da string // programa total modificado
int b // buffer de indentação

linha através de linhas: // itera sobre cada linha
  string mline = "" // linha a ser adicionada ao total

  // calcula a quantidade de espaços antes da linha (pode ser muito mais fácil)
  espaços int = 0 // espaços totais
  c através da linha: // passa por todos os caracteres da linha
    if c! = "": // se o caractere atual não for um espaço (o que significa que fomos embora todos eles
        break // interrompe a iteração através de caracteres
    spaces ++ // incrementa os espaços porque atingimos um espaço (hurr derr)

  if spaces / SPACE_SETTING <b: // se a contagem de indentações da linha atual for menor que o buffer de indentação
    mline = "} \ n" + linha // adiciona colchete ao início da linha
    b-- // decrementar buffer

  if line.endswith (":"): // se a linha terminar com um `:`
    remover: da linha
    mline + = "{" // acrescenta {
    b ++ // buffer de incremento
  total + = mline // adiciona linha modificada ao total

impressão (total)
Estágio
fonte
Você pode incluir uma explicação?
TanMath
@TanMath Adicionado o algoritmo que eu usei
fase
Funciona com o Python 2?
Wb9688 17/11/2015
@ wb9688 Não faço ideia, eu só testei com o Python 3
fase
Acabei de testar e ele funciona com o Python 2
wb9688 17/11
2

Ruby, 70

x=$_+"
"
1while x.sub! /^(( *).*):
((\2 .*?
)*)/,'\1 {
\3\2}
'
$><<x

Adiciona uma nova linha à direita. Não precisa do parâmetro de tamanho do bloco de recuo.

Execute isso com -n0(isso é realmente 68 + 2). Muito obrigado ao @primo por economizar mais de uma dúzia de bytes.

Não que Charles
fonte
Eu acho que -p0também funciona para ruby ​​( -0lê todas as entradas de uma só vez, -parmazena stdin $_e as imprime automaticamente no final).
primo
@primo Bom ponto. No caso, não ficou claro com o meu comentário acima, este não é um porto de seu código, mas o meu próprio trabalho que faz exatamente o que seu faz (mas com mais bytes)
Não que Charles
Eu entendi corretamente, apenas fornecendo uma dica para remover o (bastante detalhado) x=$<.readlines*''. Enquanto eu estou fazendo isso, sub!também tem uma sobrecarga de dois parâmetros (em vez de um paramater + bloco) que aceita uma cadeia de substituição, de modo que você pode usar \1, \2etc. em vez de precisar concatenar tudo.
primo
@primo Obrigado! Eu tentei a versão de dois parâmetros antes e a abandonei em algum momento na noite passada.
Não que Charles