web-dev-qa-db-ja.com

なぜそれほど多くの言語が文字列リテラルを単一のソース行に制限するのですか?

たとえば、Bashスクリプト言語では、次は$VARという文字列を作成し、最初の"引用符で始まり、次のエスケープされない"引用符まで続きます。

$VAR="
    hello
world!

this string preserves all
    whitespace"

これにより、連結や100万回の煩わしい\nsなしで複数行の文字列を非常に簡単に記述でき、パーサーveryを簡単に記述できます(経験から言えば)。 "([^"\\]*(?:\\.[^"\\]*)*)"のような正規表現を使用したエスケープされていない引用符。

Bashは(うまくいけば!)ミッションクリティカルな言語でもシステムプログラミング言語でもありませんが、everythingがテキストである* nxボックス用のシステムスクリプト言語なので、おそらくそれが適切です。

BashはCで記述されているため、この文字列は(おそらく)\n\thello\nworld\nなどとして格納されますが、ポイントはプログラマーが記述したソースです(そして上記ははるかに読みやすいです) )。

実際の目的で使用される多くの(私はCの影響を受けた)「適切な」言語は、文字列にリテラルの改行を含めることを許可することで未知の問題を見つけるため、以下の1つ以上を必要とします。

  • エスケープシーケンス\n(Windowsでは\r\nにコンパイルされます)

  • 特別な構文(Pyでは""" multiline string """、Goでは`multiline string`、C++ 11ではR" raw string literal "など)

  • 改行を書き込む特別な関数(ForthのCRなど。ただし、Forthは文字列に関するスクワットを知っているため、パスを取得します)

なぜより多くの言語が文字列を「暗黙的に」複数行にすることを許可しないのか、私には理解できません。

長所:

  • 使いやすさと実用性、より明確なコードなど

  • よりシンプルで、より直接的で、保守性の高いパーサー(少なくとも手書きのものの場合)

短所:

  • 悪用された場合、一部のコードが読みにくくなる可能性があります

これが事実であるという明確な理由はありますか、それとも他の多くのものと同じようにCから盲目的に採用されたのですか?さらに、パーサーを記述している、または言語を設計している場合、なぜ文字列リテラルを1行に制限する必要があるのか​​について、説得力のある議論はありますか?

5
cat

FWIW、 Ocaml は、限定された形式の複数行文字列リテラルを受け入れます。

文字列リテラルは、 "(二重引用符)文字で区切られます。2つの二重引用符は、"および\とは異なる文字のシーケンス、または文字リテラルの上記の表のエスケープシーケンスを囲みます。

長い文字列リテラルを複数行に分割できるようにするために、文字列リテラル内では、シーケンス\ newlineスペースまたはタブ(行末のバックスラッシュとそれに続く任意の数のスペースと水平方向の集計)は無視されます。

c ++ 11には 生の文字列リテラル があるため、次のようにコーディングできます。

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

したがって、いくつかの言語には複数文字列リテラルを記述する方法がいくつかあります。

しなかったが複数行の文字列を含むことを意味するが、代わりに引用符を閉じるのを忘れた場合はどうなりますか?

パーサーは、プログラムの完全に異なる部分にある別の引用に達するまでコードを噛み砕き、通常どおり続行します。文字列は解析エラーではなくなったため、これは混乱を招き、無関係なエラーを引き起こす可能性が非常に高くなります。最悪の場合、適切にコンパイルされ、まったく別のことを行うプログラムを取得します。

これは、最近のIDEでのコードの部分処理によってさらに悪化します。文字列を入力すると、自然にこのシナリオが発生します。これにより、IDEでキャッシュされたASTが大量のデータが変更されたことがわかり、インテリセンス(および同様の構成)が遅くなる)と見なされます。

16
Telastyn