2012-04-15 12 views
2

私はすべてのプログラミング言語の予約キーの単語が不思議ですか? 「If」、「While」は予約語です。 If = 3が違法であるとすれば、通常の変数や関数名として使用するべきではありません。コンパイラはsanner段階でエラーを生成します。プログラマーが予約語を使用する言語を許可すると、変数名または関数名としてIfと表示される場合はどうでしょうか?コンパイラはこれをどのように処理できますか?これはスキャナやパーサで処理されますか?意味分析は何をすべきか?プログラミング言語で予約されたキーワード

更新: 私は、これは良い練習が、ほとんどの本当の理由ではありません理解/スキャナやパーサは言語をスキャンするか、言語や何を解析acurately行うことができないので、これはサポートされていないすべてのプログラミング言語は、それが実際にあります舞台裏で?ありがとう。

+0

このように、能力は、コンパイラを「混乱させる」だけでなく、その言語でコードを読む人々にも役立ちます。結局これを許可するのはなぜですか? – kirilloid

答えて

4

あなたは間違いなくこのようなことを行うことができますが、明らかにソースコードの直感性を破壊します。これを実際に実装する限り、レクサーはまったく変更する必要はありません。レクサーがソースの "if"と一致する場合は、IFタイプのトークンを返します。

IF, LARROW, INTLITERAL, SEMICOLON 

私は可能性があります:私たちはifは変数名であり、それはパーサに供給するためのレクサーのトークンストリームは1です。

if <- 1; 

値が割り当てなってき以下の代入文を、持っていると仮定、

assignStmt::= id:i LARROW intExpr:e SEMICOLON {: RESULT = new AssignmentStatement(i, e) :} 
intExpr::= INTLITERAL:i {: RESULT = i.intVal; :} 
id::= ID:i {: RESULT = i.strVal; :} 

LARROWID:(W整数rvals \)代入文を記述するために、次の作品を持っていますIF,INTLITERALおよびSEMICOLONは、レクサーによって返されるトークンであり、assignStmt,idおよびintExprは非終端記号である端末である。 IDは、識別子(例えば、クラス/変数/メソッド名)を表す。

if文の生成に失敗した後、最終的に代入文の最初のプロダクションを入力します。私たちはid非ターミナルを展開します。唯一の生産はIDですが、一致させたいトークンはIFなので、assignStmtの生産は完全に失敗します。

assignStmt::= id:i LARROW intExpr:e SEMICOLON {: RESULT = new AssignmentStatement(i, e) :} 
intExpr::= INTLITERAL:i {: RESULT = i.intVal; :} 
id::= ID:i {: RESULT = i.strVal; :} 
    |IF {: RESULT = "if"; :} 

|は、非ターミナルの代替生産を定義していること:私がしなければならないすべてが「あれば」変数は名前を付けることができるように、私の言語については

。現在、非ターミナルのidの2番目の生産があり、現在のトークンと一致し、最終的に代入文と一致します。

AssignmentStatementは、次のように定義されたASTノードです:

class AssignmentStatement { 
    String varName; 
    int intVal; 
    AssignmentStatement(String s, int i){varName = s; intVal = i; } 
} 

パーサは、ソースが構文的に正しいことを決定すると、他に何も影響を与えてはなりません。変数の名前は、コンパイルの後半には影響しないはずです。つまり、コンパイルの実行を許可する条件を作成しない場合です。

+0

詳細な説明をいただきありがとうございます。これはまさに私が探しているものです。 –

0

まあ、私は予約されたキーワードなしでコンパイルされた言語を考えることはできません。単純にはるかに説得力があり、予約されたキーワード( 'if'は良い変数名ではありません)を使用することはめったにありません。

PHPでは、変数はドル記号で始まるので、そのように実装することができます(変数に接頭辞を付けるために非文字を使って$ ifを持つことができます)。私はそれを行うことはあまりないとは言え、仕事につくことができると思います。

1

あなたができる場合でも、なぜ地球上でそれをしたいですか?

メンテナンス可能なコードを作るだけです。

if (a==b) - if式またはブール値argを渡す関数ifの呼び出しですか?

私は、もしあなたがそれをやろうとしたら、おそらく3人のユーザーがいる奇妙な学問的なことになると思います。

私はそのような言語が存在するとは思わない

-1

[3人のユーザー;-)から燃える情け容赦の準備のためにアスベストの下着の上に置きます]。 すべての情報言語は、文法、つまりコードをどのように構築する必要があるかを示す一連のルールに基づいています。そうすれば、コードが構造的に有効であることを証明することができます。 名前を必要に応じて変更できるようにするには、コードの検証が正しく行われるように、「オンザフライ」で文法を変更する方法が必要です。

もっと実用的なレベルで、なぜこのようなことをやっているのですか?予約されたキーワードで何が間違っていますか?彼らは本当に便利で、少なくとも誰もが同じ言語を同じ方法で話します。 あなたは実際の世界の言語でこのようなことを考えることはありません...周りの言葉の意味を切り替えることを想像してみてください!誰も何も理解できないだろう!

+0

を参照してください.PL/1 ... –

1

プログラミング言語は、語彙スキャナーをパーサの前に置くことが多いため、予約語を使用する傾向があります。字句スキャナはソースコードを一連のトークンに変換するので、 ">>"トークンになり、そのようなトークンはすべてシフト演算子であり、他のもの以外のものには使用できませんトークン(引用符で囲まれた文字列のような)は、C++の一般的な問題です。 "if"のような他の単語は同じで、ある種の "if"トークンに変わり、パーサーが "if"トークンを見るたびに、それをいくつかの条件付き構文の最初の部分として扱います。もう1つの例として、JavaScriptを書くことができます。

JSON

いますが、

JSON.stringify({VAR:2})を書くことができません:({2バー})文字列化 "varは" "VAR" トークンですが、 "バー" があるので

を他のどのような識別子でもかまいません。

+0

にblackcompeの答えが記載されていますが、 'id-> IF'を許可すれば、それを単なる識別子として扱うことができます。 –

+0

これは、レクサーからパーサーまで同じ問題を延期し、それを修正するためにそこに別のレイヤーを必要とします。また、有効なコードを受け入れるだけではないことに留意してください。また、プログラムが間違っていれば、正解のエラーメッセージをほぼ正しい場所に出力することができなければなりません。あいまいな構文はそれをもっと難しくします。 –

0

任意のキーワードを許可する1つの方法は、すべての非識別子構文変数にアルファベット以外の記号を使用することです。 APLはこのアプローチを採用しており、おそらくSmalltalkもそうである(Smalltalk-80では6つの予約語がありますが、それらはすべて可変的なセマンティクスを持っています;条件のような通常キーワードは構文的に規則的なメッセージです)。

関連する問題