Perché stiamo parlando di rientro e spazi bianchi, dobbiamo solo scrivere il codice in una programmazione un linguaggio che è effettivamente progettato attorno agli spazi bianchi , poiché deve essere più semplice, giusto?
Quindi la soluzione è:
Eccolo in base64:
ICAgCQogICAgCgkJICAgIAkgCiAgICAKCQkgICAgCQkKICAgIAoJCSAgICAJICAKICAgIAoJCSAgICAJIAkKICAgIAoJCSAKIAogCQoKICAgCSAKICAgCQoJCQkgICAJCQkgCQkKCSAgCQoJICAJICAKICAgCQoJCQkgICAJIAkgCgkgIAkKCSAgCSAJCiAgIAkKCQkJICAgCSAgCQoJICAJCgkgIAkgCQogICAJCgkJCSAgIAkgICAgIAoJICAJCgkgIAkgCQogICAJCgkJCSAgIAkJCQkJIAkKCSAgCQoJICAJCSAKICAgCQoJCQkgICAJICAgCSAKCSAgCQoJICAJICAgIAogICAJCgkJCSAgIAkgCSAgIAoJICAJCgkgIAkgICAJCQogICAJCgkJCSAgIAkgCSAgCQoJICAJCgkgIAkgIAkgIAogICAJIAogICAJCgkJIAogCSAJCQkKICAgCQoJCQkJCiAgCgkKCiAgIAkgIAogICAJCgkJCQkKICAKCQoKICAgCSAJCgoJCgogICAJCSAKICAgCQkKICAgCQkKCQkJICAgCQoJICAJCQkgICAgCSAKICAgCQoJCSAKIAkgCQkJCiAgIAkKCQkJCQogIAoJCgogICAJICAgIAogICAJIAogICAJIAoJCSAKIAkgCQkJCiAgIAkKCQkJCQogIAoJCgogICAJICAgCQkKICAgCSAJCiAgIAkgCQoJCQkgICAJCgkgICAJCSAgICAJIAogICAJCgkJIAogCSAJCQkKICAgCQoJCQkJCiAgCgkKCiAgIAkgIAkgIAogICAJIAkKICAgCSAJCgkJCSAgIAkKCSAgCQkJICAgIAkgCiAgIAkKCQkgCiAJIAkJCQogICAJCgkJCQkKICAKCQoKICAgCQkKICAgCQoJCQkgICAJIAkgCgkgIAkKCSAgCQkgIAogICAJCgkJCSAgIAkJCQkgCQkKCSAgCQoJICAJCSAJCiAgIAkKCQkJICAgCQkJCQkgCQoJICAJCgkgIAkJCSAKICAgCQoJCQkgICAJCQkgCQkKCSAgCQoJICAJCQkJCiAgIAkKCQkJICAgCSAgIAkgCgkgIAkKCSAgCQkgCQkKICAgCQoJCQkgICAJIAkgCSAKCSAgCQoJICAJCQkgIAogICAJCgkJCSAgIAkgCQkJCQoJICAJCgkgIAkJCSAJCiAgIAkKCQkJICAgCSAJICAgCgkgIAkKCSAgCSAgCSAJCiAgIAkKCQkJICAgCSAJICAJCgkgIAkKCSAgCSAgCQkgCiAgIAkKCQkJCQogIAoJCgogICAJCSAgCiAgIAkgCiAgICAKCQkgCgkKCiAgIAkJIAkKICAgCQoJCQkJCiAgICAgCSAKICAgIAoJCSAgICAJCQogICAJCQoJCQkgICAJCgkgICAJCSAKCQoKICAgCQkJIAogICAJCQogICAJCQoJCQkgICAJCgkgIAkJCSAKIAkgCQkJCiAgIAkKCQkJCQogICAgIAkgCiAgICAKCQkgCgkKCiAgIAkJCQkKICAgCQoJCQkJCiAgICAgCSAJCgkJCQoJICAJIAkgCgoJCgogICAJICAJCQkKICAgCSAKICAgIAoJCSAKCQoKICAgCQkgCQkKICAgCQoJCQkJCiAgICAgCSAKICAgCSAKCQkgCgkKCiAgIAkJCSAgCiAgIAkgIAoJCQkgICAJIAkJCQkKCSAgCQoJICAJCQkJIAogICAJCgkJCQkKICAKCQoKICAgCQkJIAkKICAgCSAgCgkJCSAgIAkgCQkJCQoJICAJCgkgIAkJCQkJCiAgIAkKCQkJCQogIAoJCgogICAJCQkJIAogICAJCgkJCQkKICAgICAJIAogICAJCQoJCSAKCQoKICAgCQkJCQkKICAgCQoJCQkJCiAgICAgCSAKICAgCSAgCgkJIAoJCgogICAJICAJIAkKICAgCSAJCiAgIAkgCQoJCQkgICAJCgkgICAJCSAgICAJCgkJCQkKICAKCQoKICAgCSAgCQkgCiAgIAkgCQogICAJIAkKCQkJICAgCQoJICAJCQkgICAgCQoJCQkJCiAgCgkKCiAgIAkJCQogICAJIAkgCgkKICAgICAJCQoJCQkKICAgCSAgCQogCiAKCSAgCSAgIAogCiAKCQkgCSAgIAogICAJICAgICAKCQogICAgIAkgICAgIAoJCiAgICAgCQoJICAJCiAKIAkgIAkKCiAgIAkgICAKCgkKCiAgIAkgCSAJCiAgIAkKCQkJICAgCSAJIAoJICAJCgkgIAkJICAgCiAgIAkKCQkJICAgCSAgIAkgCgkgIAkKCSAgCQkgIAkKICAgCQoJCQkJCiAgCgkKCiAgIAkJICAgCiAgIAkgCiAgICAKCQkgCgkKCiAgIAkJICAJCiAgIAkgIAoJCQkgICAJIAkJCSAgCgkgIAkKCSAgCQkgCSAKICAgCSAKICAgCQoJCSAgICAJCgkJCQkKICAKCQoKICAgCQkgCSAKICAgCQoJCQkJCiAgCgkKCiAgIAkgCQkgCiAgIAkKCQkJICAgCSAJCQkJCgkgIAkKCSAgCSAgICAgCiAgIAkKCQkJCQogIAoJCgogICAJICAgICAKICAgCSAgCgkJCSAgIAkgCSAJIAoJICAJCgkgIAkgICAgCQogICAJCgkJCQkKICAKCQoKICAgCSAgICAJCiAgIAkKCQkJCQogICAgIAkgCiAgIAkKCQkgCgkKCiAgIAkgCQkJCiAgIAkKCQkJICAgCSAJIAoJICAJCgkgIAkgICAJIAogICAJCgkJCQkKICAKCQoKICAgCSAgIAkgCiAgIAkgCiAgICAKCQkgCgkKCiAgIAkKICAgCSAgCiAgIAkKCQkJCQkgICAgCQoJCgkgICAgCSAKCQkJCgkgIAkgCSAKICAgCSAKCQkJICAgCQoJICAJCgkgIAkgICAJCiAgIAkgCgkJCSAgIAkgCgkgIAkKCSAgCSAgCSAKICAgCSAKCQkJICAgCQkKCSAgCQoJICAJICAJCQogICAJIAoJCQkgICAJICAKCSAgCQoJICAJIAkgIAoKICAgCSAgIAkKCiAJIAkJCgogCiAJIAkJCgogICAJIAkgCgogCSAJIAoKIAogCSAJCQoKICAgCSAgCSAKCiAJIAkgCSAJCgogCiAJIAkJCgogICAJICAJCQoKIAkgCSAJCSAKCiAKIAkgCQkKCiAgIAkgCSAgCgogCSAJIAkJCQoKICAgCSAJCQoKIAogCQoKCgo=
Per coloro che hanno problemi a stampare il codice su un documento, ecco la versione annotata (puoi trovare un compilatore per questo alla fine della risposta):
# heap structure:
# 1: read buffer
# 2: parser state
# 0: before indentation
# 1: after indentation
# 2: inside a string literal
# 3: inside a multiline comment
# 4: inside a single line comment
# 3: identation
# 4: old read buffer
# 5: parenthesis nesting amount
# -------------------
# initialize heap
# -------------------
SS 1 | SS 0 | TTS # [1] := 0
SS 2 | SS 0 | TTS # [2] := 0
SS 3 | SS 0 | TTS # [3] := 0
SS 4 | SS 0 | TTS # [4] := 0
SS 5 | SS 0 | TTS # [5] := 0
LSL 1 # goto L1
# -------------------
# sub: determine what to do in state 0
# -------------------
LSS 2 # LABEL L2
SS 1 | TTT | SS 59 | TSST | LTS 4 # if [1] == ; GOTO L4
SS 1 | TTT | SS 10 | TSST | LTS 5 # if [1] == \n GOTO L5
SS 1 | TTT | SS 9 | TSST | LTS 5 # if [1] == \t GOTO L5
SS 1 | TTT | SS 32 | TSST | LTS 5 # if [1] == ' ' GOTO L5
SS 1 | TTT | SS 125 | TSST | LTS 6 # if [1] == } GOTO L6
SS 1 | TTT | SS 34 | TSST | LTS 16 # if [1] == " GOTO L16
SS 1 | TTT | SS 40 | TSST | LTS 35 # if [1] == ( GOTO L35
SS 1 | TTT | SS 41 | TSST | LTS 36 # if [1] == ) GOTO L36
SS 2 | SS 1 | TTS # [2] := 1
LST 7 # call L7
SS 1 | TTT | TLSS # print [1]
LTL # return
LSS 4 # label L4 - ; handler
SS 1 | TTT | TLSS # print [1]
LTL # return
LSS 5 # label L5 - WS handler
LTL # return
LSS 6 # label L6 - } handler
# decrease identation by one
SS 3 | SS 3 | TTT | SS 1 | TSST | TTS # [3] := [3] - 1
SS 2 | SS 1 | TTS # [2] := 1
LST 7 # call L7
SS 1 | TTT | TLSS # print [1]
LTL # return
LSS 16 # label L16 - " handler
SS2 | SS 2 | TTS # [2] := 2
LST 7 # call L7
SS1 | TTT | TLSS # print [1]
LTL
LSS 35
SS 5 | SS 5 | TTT | SS 1 | TSSS | TTS # [5] := [5] + 1
SS 2 | SS 1 | TTS # [2] := 1
LST 7 # call L7
SS1 | TTT | TLSS # print [1]
LTL
LSS 36
SS 5 | SS 5 | TTT | SS 1 | TSST | TTS # [5] := [5] - 1
SS 2 | SS 1 | TTS # [2] := 1
LST 7 # call L7
SS1 | TTT | TLSS # print [1]
LTL
# -------------------
# sub: determine what to do in state 1
# -------------------
LSS 3 # LABEL L3
SS 1 | TTT | SS 10 | TSST | LTS 12 # if [1] == \n GOTO L12
SS 1 | TTT | SS 123 | TSST | LTS 13 # if [1] == { GOTO L13
SS 1 | TTT | SS 125 | TSST | LTS 14 # if [1] == } GOTO L14
SS 1 | TTT | SS 59 | TSST | LTS 15 # if [1] == ; GOTO L15
SS 1 | TTT | SS 34 | TSST | LTS 27 # if [1] == " GOTO L27
SS 1 | TTT | SS 42 | TSST | LTS 28 # if [1] == * GOTO L28
SS 1 | TTT | SS 47 | TSST | LTS 29 # if [1] == / GOTO L29
SS 1 | TTT | SS 40 | TSST | LTS 37 # if [1] == ( GOTO L37
SS 1 | TTT | SS 41 | TSST | LTS 38 # if [1] == ) GOTO L38
SS 1 | TTT | TLSS # print [1]
LTL # return
LSS 12 # LABEL L12 - \n handler
SS 2 | SS 0 | TTS # [2] := 0
LTL # return
LSS 13 # LABEL L13 - { handler
SS 1 | TTT | TLSS # print [1]
SS 2 | SS 0 | TTS # [2] := 0
SS 3 | SS 3 | TTT | SS 1 | TSSS | TTS # [3] := [3] + 1
LTL # return
LSS 14 # LABEL L14 - } handler
SS 3 | SS 3 | TTT | SS 1 | TSST | TTS # [3] := [3] - 1
LST 7 # call L7
SS 1 | TTT | TLSS # print [1]
SS 2 | SS 0 | TTS # [2] := 0
LTL # return
LSS 15 # LABEL L15 - ; handler
SS 1 | TTT | TLSS # print [1]
SS 5 | TTT | LTS 10 # if [5] == 0 GOTO L39
LTL
LSS 39
SS 2 | SS 0 | TTS # [2] := 0
LTL # return
LSS 27 # label L27 - " handler
SS1 | TTT | TLSS # print [1]
SS2 | SS 2 | TTS # [2] := 2
LTL
LSS 28 # label L28 - * handler - this might start a comment
SS 4 | TTT | SS 47 | TSST | LTS 30 # if [4] == / GOTO L30
SS1 | TTT | TLSS # print [1]
LTL
LSS 29 # label L29 - / handler - this might start a comment
SS 4 | TTT | SS 47 | TSST | LTS 31 # if [4] == / GOTO L31
SS1 | TTT | TLSS # print [1]
LTL
LSS 30 # label L30 - /* handler
SS1 | TTT | TLSS # print [1]
SS2 | SS 3 | TTS # [2] := 3
LTL
LSS 31 # label L31 - // handler
SS1 | TTT | TLSS # print [1]
SS2 | SS 4 | TTS # [2] := 4
LTL
LSS 37
SS 5 | SS 5 | TTT | SS 1 | TSSS | TTS # [5] := [5] + 1
SS1 | TTT | TLSS # print [1]
LTL
LSS 38
SS 5 | SS 5 | TTT | SS 1 | TSST | TTS # [5] := [5] - 1
SS1 | TTT | TLSS # print [1]
LTL
# -------------------
# sub: print identation
# -------------------
LSS 7 # label L7 - print identation
SS 10 | TLSS # print \n
SS 3 | TTT # push [3]
LSS 9 # label L9 - start loop
SLS | LTS 8 # if [3] == 0 GOTO L8
SLS | LTT 8 # if [3] < 0 GOTO L8 - for safety
SS 32 | TLSS # print ' '
SS 32 | TLSS # print ' '
SS 1 | TSST # i := i - 1
LSL 9 # GOTO L9
LSS 8 # label L8 - end loop
LTL #
# -------------------
# sub: L21 - string literal handler
# -------------------
LSS 21
SS 1 | TTT | SS 10 | TSST | LTS 24 # if [1] == \n GOTO L24
SS 1 | TTT | SS 34 | TSST | LTS 25 # if [1] == " GOTO L25
SS 1 | TTT | TLSS # print [1]
LTL
LSS 24 # \n handler - this should never happen, but let's be prepared and reset the parser
SS 2 | SS 0 | TTS # [2] := 0
LTL # return
LSS 25 # " handler - this might be escaped, so be prepared
SS 4 | TTT | SS 92 | TSST | LTS 26 # if [4] == \ GOTO L26
SS 2 | SS 1 | TTS # [2] := 1
SS 1 | TTT | TLSS # print [1]
LTL
LSS 26 # \\" handler - escaped quotes don't finish the literal
SS 1 | TTT | TLSS # print [1]
LTL
# -------------------
# sub: L22 - multiline comment handler
# -------------------
LSS 22
SS 1 | TTT | SS 47 | TSST | LTS 32 # if [1] == / GOTO L32
SS 1 | TTT | TLSS # print [1]
LTL
LSS 32
SS 4 | TTT | SS 42 | TSST | LTS 33 # if [4] == * GOTO L33
SS 1 | TTT | TLSS # print [1]
LTL
LSS 33
SS 1 | TTT | TLSS # print [1]
SS 2 | SS 1 | TTS # [2] := 1
LTL
# -------------------
# sub: L23 - singleline comment handler
# -------------------
LSS 23
SS 1 | TTT | SS 10 | TSST | LTS 34 # if [1] == \n GOTO L34
SS 1 | TTT | TLSS # print [1]
LTL
LSS 34
SS 2 | SS 0 | TTS # [2] := 0
LTL
# -------------------
# main loop
# -------------------
LSS 1 # LABEL L1
SS 4 | SS 1 | TTT | TTS # [4] := [1]
SS 1 | TLTS # [1] := read
SS 2 | TTT | LTS 10 # if [2] == 0 GOTO L10
SS 2 | TTT | SS 1 | TSST | LTS 17 # if [2] == 1 GOTO L17
SS 2 | TTT | SS 2 | TSST | LTS 18 # if [2] == 2 GOTO L18
SS 2 | TTT | SS 3 | TSST | LTS 19 # if [2] == 3 GOTO L19
SS 2 | TTT | SS 4 | TSST | LTS 20 # if [2] == 4 GOTO L20
LSS 17
LST 3 # call L3
LSL 11 # GOTO L11
LSS 10 # label L10
LST 2 # call L2
LSL 11
LSS 18
LST 21
LSL 11
LSS 19
LST 22
LSL 11
LSS 20
LST 23
LSS 11 # label L11
LSL 1 # goto L1
LLL # END
Questo è ancora in corso, anche se si spera che dovrebbe superare la maggior parte dei criteri!
Funzionalità attualmente supportate:
- correzione dell'identificazione basata sui caratteri
{
e }
.
- aggiungere una nuova riga dopo
;
- gestire i caratteri di rientro all'interno dei letterali delle stringhe (incluso il fatto che i letterali delle stringhe non vengono chiusi quando si incontra a
\"
)
- gestire i caratteri di rientro all'interno di commenti singoli e multilinea
- non aggiunge caratteri di nuova riga se tra parentesi (come un
for
blocco)
Input di esempio (ho aggiunto alcuni commenti di Quincunx basati su casi limite, in modo da poter verificare che si comporti correttamente):
/* Hai Worldz. This code is to prevent formatting: if(this_code_is_touched){,then+your*program_"doesn't({work)}correctl"y.} */
#include<stdio.h>
#include<string.h>
int main() {
int i;
char s[99];
printf("----------------------\n;;What is your name?;;\n----------------------\n\""); //Semicolon added in the {;} string just to annoy you
/* Now we take the {;} input: */
scanf("%s",s);
for(i=0;i<strlen(s);i++){if(s[i]>='a'&&s[i]<='z'){
s[i]-=('a'-'A'); //this is same as s[i]=s[i]-'a'+'A'
}}printf("Your \"name\" in upper case is:\n%s\n",s);
return 0;}
Esempio di output:
[~/projects/indent]$ cat example.c | ./wspace indent.ws 2>/dev/null
/* Hai Worldz. This code is to prevent formatting: if(this_code_is_touched){,then+your*program_"doesn't({work)}correctl"y.} */
#include<stdio.h>
#include<string.h>
int main() {
int i;;
char s[99];;
printf("----------------------\n;;What is your name?;;\n----------------------\n\"");; //Semicolon added in the {;} string just to annoy you
/* Now we take the {;} input: */
scanf("%s",s);;
for(i=0;i<strlen(s);i++){
if(s[i]>='a'&&s[i]<='z'){
s[i]-=('a'-'A');; //this is same as s[i]=s[i]-'a'+'A'
}
}
printf("Your \"name\" in upper case is:\n%s\n",s);;
return 0;;
}
Si noti che poiché gli spazi bianchi non supportano il controllo EOF dell'intero, viene generata un'eccezione, che è necessario eliminare. Poiché non vi è alcun modo di verificare la presenza di EOF negli spazi bianchi (per quanto ne so, questo è il mio primo programma di spazi bianchi), questo è inevitabile, spero che la soluzione conti ancora.
Questo è lo script che ho usato per compilare la versione annotata in spazi bianchi appropriati:
#!/usr/bin/env ruby
ARGF.each_line do |line|
data = line.gsub(/'.'/) { |match| match[1].ord }
data = data.gsub(/[^-LST0-9#]/,'').split('#').first
if data
data.tr!('LST',"\n \t")
data.gsub!(/[-0-9]+/){|m| "#{m.to_i<0?"\t":" "}#{m.to_i.abs.to_s(2).tr('01'," \t")}\n" }
print data
end
end
Correre:
./wscompiler.rb annotated.ws > indent.ws
Si noti che questo, oltre a convertire i S
, L
e T
personaggi, permettono anche commenti a linea singola con #
, e in grado di convertire automaticamente i numeri e semplici letterali di caratteri nella loro rappresentazione spazi bianchi. Sentiti libero di usarlo per altri progetti di spazi bianchi, se vuoi