web-dev-qa-db-ja.com

より多くの言語が再帰的/ネストされたコメントをサポートしないのはなぜですか?

可能性のある複製:
なぜほとんどのプログラミング言語がブロックコメントをネストしないのですか?

私が使用したほとんどの言語は、再帰的/ネストされたコメントをサポートしていません。

  1. 言語デザイナーがこれを実装しないことを選択する理由はありますか?
  2. 一見複雑ですか?
  3. 望ましくない結果になりますか?

私は次のような問題がある可能性があることを知っています:

/*
    string Str = "aslfkalfksnflkn/*aslkfasnflkn";

*/

Console.WriteLine("asdoadokn");

ただし、非再帰的な問題でも同じ問題が発生する可能性があるため(コメントの文字列で* /を検討してください)、これは適切な議論ではないと思います。

14
George Duckett

問題は、再帰コメントが実際にparseコメントセクションを強制し、通常のレクサーの範囲外に押し出して、さらに多くの問題を引き起こす可能性があることです。

復習者として:コンパイラには通常、さまざまなジョブを持ついくつかの異なるステージがあり、最初のステージはレクサーです。これは、入力プログラムを取得し、それを一連のトークン(それぞれにキーワード、識別子、または演算子)、およびこのトークンのシーケンスを抽象構文ツリー(AST)に構造化するパーサー。

字句解析プログラムのスコープについては、字句解析は通常、正規表現で実行できることに注意してください。再帰的コメントのようなブラケットのような構造は、正規表現では解析できません(コンテキストフリーの文法を参照)。そのため、字句解析プログラムは、たとえば再帰下降パーサーを介して実装する必要があります。

さらに、Cおよび同様の言語(最も有名なのは/ ** /コメント構文を使用しました)には、プリプロセッサがあり、未使用のコードのチャンクが単にラップされていたため、コードの大きなチャンクをコメントアウトする必要はありませんでした。

#if 0
....
#endif

これは、問題を2番目のはるかに単純なコンパイラ(プリプロセッサ)に委任することで、解析の問題を回避しました。

要約:再帰的なコメントはコンパイルをより複雑にするため、通常は許可されません。また、Cスタイルのコメントがあり、プリプロセッサーがない言語のみが本当に必要です。もちろん、Javaはその中にありますが、残念です。

編集:これは、再帰的なコメントが不可能または非常に難しい場合さえあるという意味ではありません。再帰下降レクサーを使用したり、レクサーの前にコメントをフィルターするためのプリプロセッサーを置くことができます。ただし、どちらのアプローチも標準モデル(REを使用してレクサーを自動ビルドし、EBNFを使用してパーサーを自動ビルドする)と比較してかなりのコストがかかり、ゲインはかなり小さいです。

27
thiton

私はこれであなたと一緒です。大規模な古いコードベースを使用すると、ハック、コメントアウトされたコード、およびその他のダートとグリットに関するコメントが散らばっており、/*...*/コメントに記載されているCインターフェイスは言うまでもありません。それらの一部をコメント化する必要がある場合、/*...*/コメントを使用することは、ネストしないので、ほとんど決して選択肢ではありません。

C++の複雑さと比較して、/**/(および多分//)のコメントの解析は非常に簡単なはずなので、「コンパイラーをさらに複雑にする」ことも理由とは思いません。実際、私はBorland C++(90年代)がネストされたコメントを解析するオプションを提供していることを思い出しているようです。

しかし、非標準のソリューションの問題は、後でコードを移植する必要がある場合にそれらを使用できないことです。 (そして、C++では、誰がそれを排除するでしょうか?)

したがって、これが標準化されれば、それは改善になるということに同意します。

それまでの間、//コメントを使用してコードのチャンクをコメントアウトします。幸い、ほとんどの最新のエディター/ IDEには、これを一度に複数の行に適用するオプションがあります。

8
sbi

これを一度行うようにCコンパイラを変更しましたが、それほど難しくはありませんでした。字句スキャナーですべて処理されているので、パーサーの本質をいじくる必要はありません。実際には、ネストレベルを追跡し、文字列区切り文字内のすべてを無視するだけです。

4
TMN

複数行にまたがるコメントは、ルールではなく例外であるべきです。

Cでも、標準の//ではなくC++スタイルの/* */を使用しています。

コードの大部分をコメントアウトする必要がある場合は、ネストをサポートする#if 0プリプロセッサディレクティブを使用します。

3
mouviciel

Newspeak には、ネスト可能な構造化されたコメントがあります。 そしてそれは非常に単純な文法を持っているので、明らかに「一見複雑」ではありません。

3
Jörg W Mittag

これは再帰です:

public void recursion()
{
    recursion();
}

再帰的なコメントがどのようになるかわかりません。

一方、ネストされたコメントは理にかなっており、実際にはある程度機能しています。単一行コメントを複数行コメント内にネストできます。

/* No longer use this!
// This is a method.
public void method()
{
}
*/

プログラマーの観点から、あなたが求めていることをサポートすることは、完全に理にかなっています。

/* No longer use this!
// This is a method.
public void method()
{
    /* Disabled!
       doInterestingStuff();
       ...
    */
}
*/

プログラミング言語は、プログラマーが自分の意図を表現できる単なるツールであることを考えると、これをサポートするintentionは付加価値になります。

技術的な側面については、コメントすることはできませんが、他の回答のいくつかはすでにその情報を提供しているようです。

1
Steven Jeuris

1つの理由は、おそらく既存のコードベースとの互換性です。 Cのような言語は通常、Cと同じようにすべてを実行し、031 == 25(8進リテラル、誰がそれらを必要としたのか?)

別の理由はより哲学的です:コメントは(例えば)/ *で始まり、次の* /で終わります、そしてそれらの間にあるものは何でもまったく関係ありませんです。ネストされたコメントも、コメントの構文を定義する必要があります。

ところで、そのピースコードが必要なくなった場合は、完全に削除してVCSに任せて、古いバージョンを保持するのはどうでしょうか。コメント付きコードはコードのにおいです。

1
user281377