32

例(C):

int break = 1;
int for = 2;

なぜコンパイラはそれを推測するのにまったく問題があり、ここbreakforは変数なのですか?


だから、キーワードが必要なのは

  • プログラムを読みやすくしたい
  • 今日のすでに複雑なコンパイラの仕事を過度に複雑にしたくありません
  • しかし、最も重要なことは、いくつかの「キーワード」がいくつかの特別なアクションのために予約されている場合、言語ははるかに強力です。そうすれば、言語は、明確な方法でforループを実装しようとして死ぬのではなく、より高いレベルで役立つと考えることができます。
4

13 に答える 13

29

必須ではありません -- Fortran は単語を予約していないので、次のようになります:

if if .eq. then then if = else else then = if endif

完全に合法です。これにより、コンパイラが言語を解析しにくくなるだけでなく、多くの場合、人がエラーを読んだり見つけたりすることがほとんど不可能になります。たとえば、古典的な Fortran を考えてみましょう (たとえば、Fortran 77 まで - 最近は使用していませんが、少なくとも最近の標準でこのようないくつかの点が修正されていることを願っています)。Fortran の DO ループは次のようになります。

DO 10 I = 1,10

それらが並んでいないと、これがどのように異なっていたかを見逃してしまうことがおそらくわかるでしょう。

DO 10 I = 1.10

残念ながら、後者は DO ループではありません。つまり、1.10名前付きの変数に値を代入するだけですDO 10 I(そうです、名前にスペースを使用することもできます)。Fortran は暗黙の (宣言されていない) 変数もサポートしているため、これはすべて完全に正当であり (または正当であった)、一部のコンパイラは警告なしでそれを受け入れることさえあります!

于 2010-03-16T06:04:43.150 に答える
20

次に、次のようなステートメントに遭遇したとき、コンピューターは何をしますか。

while(1) {
  ...
  if (condition)
    break;
}

それは本当に壊れるべきですか?それともそれを扱うべき1;ですか?

場合によっては、言語があいまいになるか、微妙な構文を推測できる非常にスマートなパーサーを作成する必要がありますが、それは不要な余分な作業です。

于 2010-03-16T05:55:47.613 に答える
8

彼らはしません。PL/1 にはキーワードがないことで有名です。すべての「キーワード」 (BEGIN、DO、...) は、変数名としても使用できます。しかし、これを許すということは、本当にあいまいなコードを書くことができるということです: IF DO>BEGIN THEN PRINT:=CALL-GOTO; 「ステートメントキーワード」を言語として予約しても、その名前のセットが控えめであれば、通常は損失ではありません (PL/1 を除いて、私がこれまでに見たすべての言語でそうであるように:-)。

APL にはキーワードがないことでも有名です。しかし、複雑な演算子を記述するための約 200 の驚くべき象徴的なシンボルのセットがあります。(「ドミノ」演算子 [質問しないでください!] は、電卓の分割記号が中央にある四角いボックスです) この場合、言語の設計者はキーワードの代わりにアイコンを使用しました。その結果、APL は「書き込み専用」言語であるという評判を得ています。

結論: 要件ではありませんが、キーワードがプログラマーに知られている小さなセットから予約された識別子である場合、プログラムがはるかに読みやすくなる傾向があります。(一部の言語では、「キーワード」は「.」などの特殊な句読点で開始して、考えられるすべての識別子を使用できるようにすることを主張していますが、これは入力の手間やページの乱雑さの価値はありません。キーワード セットが小さい場合は、キーワードに一致する「識別子」を避けてください)。

于 2010-03-16T06:04:59.470 に答える
6

C とタグ付けされているため、元の C 言語では、デフォルトですべての変数が type として定義されていましintた。

これはfoo;、 type の変数を宣言することを意味しますint

あなたがそうしているとしましょうbreak;breakという名前の変数を宣言するか、キーワードを使用するかを、コンパイラはどのように判断するのbreakでしょうか。

于 2010-03-16T07:40:24.710 に答える
4

いくつかの理由:

  • サンプルでは、​​キーワードが明確に見える場合があります。しかし、変数 'break' または変数 'for' を使用する場所はそれだけではありません。

  • パーサーを書くのははるかに難しく、エラーが発生しやすく、利益はほとんどありません。

  • ライブラリ内の関数またはプロシージャ名としてキーワードを使用すると、望ましくない、おそらくセキュリティ関連の副作用が生じる可能性があります。

于 2010-03-16T05:55:44.633 に答える
4

他の人が言ったように、これにより、コンパイラがソース コードを簡単に解析できるようになります。しかし、もう少し言いたいことがあります。ソース コードを読みやすくすることもできます。次の例を検討してください。

if (if > 0) then = 10 end if

2 番目の「if」と 2 番目の「then」は変数ですが、その他はそうではありません。この種のコードは読めないと思います。:)

于 2010-03-16T06:08:47.090 に答える
2

私たちが持っている小さな正気のポイントを維持したいので:

void myfunction(bool) { .. };

funcp while = &myfunction;
while(true); 
于 2010-03-16T09:00:07.560 に答える
2

次のように記述すると、コンパイラに問題が発生します。

while(*s++);
return(5);

それはループですか、それとも という名前の関数の呼び出しwhileですか? 現在の関数から値 5 を返したいですか、それとも という名前の関数を呼び出したいreturnですか?

特別な意味を持つ構造が、それらを明確に参照するために使用できる特別な名前を持っているだけである場合、多くの場合、物事が単純化されます。

于 2010-03-16T05:58:10.987 に答える
2

C++ について言えば、すでに非常に複雑な文法を持っています。たとえば、キーワードを変数名として使用できるようにすると、さらに複雑になります。

于 2010-03-16T05:59:24.427 に答える
0

FWIW、Tclには予約語がありません。「if」、「break」などの名前の変数と関数を使用できます。トークンの解釈は、コンテキストに完全に依存します。同じトークンは、あるコンテキストではコマンド、別のコンテキストでは変数、または別のコンテキストではリテラル文字列を表すことができます。

于 2010-03-19T16:33:47.110 に答える
0

多くの場合、次の例のように、コンパイラがキーワードを通常の識別子として解釈することが可能です。

int break = 1;
int for = 2;

実際のところ、私はこれを行う単純なアセンブリのようなおもちゃの言語用のコンパイラを作成しましたが、そのような場合はユーザーに警告します。

ただし、構文がキーワードと識別子があいまいになるように定義されている場合があります。

int break;

while(...)
{
    break; // <-- treat this as expression or statement?
}

そして最も明白な理由は、コードが人間にとってより読みやすいように、編集者がキーワードを強調することです。キーワードを識別子として扱うことを許可すると、コードの強調表示が難しくなり、コードの読みやすさが低下します。

于 2010-03-19T16:40:10.677 に答える
0

言語定義に応じて、コンパイラはキーワードを必要とする場合と必要としない場合があります。何をすべきかわからない場合、優先ルールを適用しようとするか、単に失敗する可能性があります。
例:

void return(int i){printf("%d",i);}
public int foo(int a)
{
  if(a > 2)return (a+1)*2;
  return a + 3;
}

a が 2 より大きい場合はどうなりますか?

  • 言語仕様では、コンパイラが失敗する必要がある場合があります
  • 言語仕様では、コンパイラが return 関数を使用する必要がある場合があります
  • 言語仕様では、コンパイラが返す必要がある場合があります

キーワードを使用しない言語を定義できます。すべての記号を置き換えることができる言語を定義することもできます (記号自体は非常に短いキーワードにすぎないため)。
問題はコンパイラではありません。仕様が完全でエラーがない場合は機能します。問題は PEBCAD です。この言語の機能を使用するプログラムは、シンボル定義を追跡する必要があるため、読みにくくなります。

于 2010-03-19T15:25:23.857 に答える
0

パーサーを書くことは不可能ではないにしても、非常に奇妙に見えると思います。例えば

int break = 1;
while (true) {
   // code to change break
   if (!break) break;   // not very readable code.
}
于 2010-03-16T06:24:48.397 に答える