Perché così tante lingue limitano le stringhe letterali a una singola riga sorgente? [chiuso]

4

In, ad esempio, il linguaggio di scripting di Bash, quanto segue crea una stringa chiamata $VAR che inizia alla prima virgola " e continua fino alla prossima citazione " senza escape.

$VAR="
    hello
world!

this string preserves all
    whitespace"

Questo rende molto facile scrivere stringhe multiline senza concatenazione o un milione fastidioso \n s ovunque, e rende il parser molto facile da scrivere (parlando dall'esperienza) perché puoi solo trangugiare tutto tra virgolette senza escape con una regex come "([^"\]*(?:\.[^"\]*)*)" o giù di lì.

Bash è (si spera!) non un linguaggio mission-critical o di programmazione dei sistemi, ma è un linguaggio di scripting per sistemi destinato a caselle * nx su cui tutto è testo, quindi forse è apt .

Ricorda che Bash è scritto in C, e quindi questa stringa è (probabilmente) memorizzata come \n\thello\nworld\n etc, ma il punto è la fonte scritta dal programmatore (e quanto sopra è molto più leggibile ).

Molti linguaggi "appropriati" (a mio avviso influenzato da C) utilizzati per scopi reali trovano alcuni problemi sconosciuti che consentono alle stringhe di contenere righe nuove letterali e quindi richiedono uno o più dei seguenti elementi:

  • escape sequences \n (che viene compilato in \r\n su Windows)

  • sintassi speciale ( """ multiline string """ in Py, 'multiline string' in Go o R" raw string literal " in C ++ 11, ecc.)

  • funzioni speciali per scrivere nuove righe (di Forth CR , ad esempio, anche se Forth ottiene un passaggio perché conosce lo squat sulle stringhe)

Non capisco perché più lingue non consentono alle stringhe di essere "implicitamente" multiline.

Pro:

  • facilità d'uso e amp; praticità, codice più chiaro, ecc.

  • parser più semplice, più diretto e quindi più gestibile (almeno per quelli scritti a mano)

Contro:

  • può rendere un po 'meno leggibile il codice, in caso di abuso

Esiste una ragione esplicita in questo caso, o è stata solo ciecamente (?) adottata da C come tante altre cose? Inoltre, se sto scrivendo un parser o progettando un linguaggio, c'è un argomento convincente sul perché dovrei limitare i letterali di stringa a una singola riga?

    
posta cat 11.02.2016 - 15:28
fonte

4 risposte

4

FWIW, Ocaml accetta una forma limitata di stringa letterale a più righe:

String literals are delimited by " (double quote) characters. The two double quotes enclose a sequence of either characters different from " and \, or escape sequences from the table given above for character literals.

To allow splitting long string literals across lines, the sequence \newline spaces-or-tabs (a backslash at the end of a line followed by any number of spaces and horizontal tabulations at the beginning of the next line) is ignored inside string literals.

e C ++ 11 ha valori letterali stringa raw in modo da poter codificare:

const char* s1 = R"foo(
Hello
World
)foo";

Quindi diverse lingue hanno alcuni modi per scrivere valori letterali multistringa.

    
risposta data 11.02.2016 - 16:01
fonte
14

Che cosa succede quando non significa avere una stringa multi-linea, ma hai invece dimenticato di chiudere la citazione?

Il parser masticherà il codice finché non raggiunge un'altra citazione in una parte completamente diversa del programma, quindi procederà normalmente. Ciò probabilmente causerà errori confusi e non correlati poiché la stringa non è più l'errore di analisi. Nel peggiore dei casi, ottieni un programma che si compila correttamente e fa qualcosa di completamente diverso.

Questo è aggravato dall'elaborazione parziale del codice nei moderni IDE. Mentre stai digitando la stringa, creerai questo scenario in modo naturale. Ciò farà sì che l'IDE lanci l'AST memorizzato nella cache poiché vede che un sacco di cose sono cambiate, portando a un intellisenso più lento (e costrutti simili).

    
risposta data 11.02.2016 - 15:44
fonte
-2

Il preprocessore ha già dato un significato ai caratteri newline. Non è possibile annullarlo completamente a un livello superiore. Confronto:

char s1[] = "This is how macros work in C\nExample\n    #define IS_GOOD 1\n";

con

char s2[] = "This is how macros work in C
Example
    #define IS_GOOD 0
";

Chiaramente il secondo è più facile da leggere (in un ipotetico compilatore C che accetta valori letterali stringa multipli).

Inoltre non fa quello che ti aspettavi. s2 non contiene affatto un esempio di codice C, quello che hai effettivamente ottenuto è stato:

char s2[] = "This is how macros work in C\nExample\n";

oops.

Oppure, puoi anche cambiare la grammatica del preprocessore, rendendola consapevole delle quotazioni. Quindi si perde la possibilità di espandere macro a definizioni contenenti virgolette. Quasi niente di meglio.

Le cose che causano risultati inaspettati e confusi non sono caratteristiche desiderabili.

    
risposta data 11.02.2016 - 18:25
fonte
-3

Non posso rispondere sul "perché"; per quanto ne so i progettisti di linguaggi tendono a copiare le "cose cattive" tante volte quanto le "cose buone" quando progettano una lingua basata su altre lingue.

Devo dire che usare RegEx per analizzare il tuo codice non è il modo migliore per farlo e scrivere un parser che possa tenere traccia delle stringhe multilinea potrebbe essere più difficile di quanto ti aspetteresti, specialmente se l'indentazione fa parte di la lingua.

Ciò che posso dire sulla progettazione di un nuovo formato di stringa è di non usare nemmeno la virgoletta doppia " . Se dovessi progettare una lingua, userei le parentesi per incapsulare "content" e implementare una funzione nella libreria standard in questo modo:

let foo = String(This is my string which can be multiline and does not
                 need escape characters for anything other than \( and \).)
    
risposta data 11.02.2016 - 16:09
fonte

Leggi altre domande sui tag