最近のほとんどの言語では予約語を使用して、キーワードなどが識別子として使用されないようにしています。
予約語はさておき、キーワードを識別子として使用できる言語を想定しましょう。 (たとえば、Rubyでは、キーワードをメソッド名として使用できます)。コンパイル中に、このあいまいさをどのように処理しますか?
字句解析フェーズは、その周りのトークンを考慮する必要があるため、適切とは思えません。パーサはあいまいでないトークンを使用するのが理想的であるため、解析フェーズも適切とは言えません。
自分で設計する必要がある場合は、レクサーにあいまいなトークンを生成させ、その周りのトークンのコンテキストであいまいなトークンを考慮する別のレベルを設定するとします(たとえば、あいまいなトークンはdef
キーワード?それは識別子でなければなりません。)次に、明確なトークンをパーサーに渡します。
キーワードを識別子として使用できる言語で、コンパイラがそれらを区別するための標準的な方法は何ですか?
Rubyで気づいた場合、そのような名前のメソッドを直接呼び出すことはできません。あなたはできない
begin()
できるよ
obj.begin()
そこにあなたがのような文法を持つことができるので:
*Arguments* :
"(" ")"
*MemberExpression* :
*MemberExpression* "." *IdentifierName*
*CallExpression* :
*MemberExpression* *Arguments*
(簡潔にするために、例とは無関係のルールは省略しています)
それを認識します。ルールIdentifierをIdentifierNameから分離するだけです:
*Identifier*:
*IdentifierName* **but not reserved Word**
*IdentifierName*:
//Rules for identifier names here
スターターbegin
がある場合
begin()
次に、すでに次のようなルールをアクティブにしました
*Block*:
"begin" *indent* *statement* *outdent* "end"
そしてRubyはあなたが何を意味するのか理解しようとせず、それは単なるブロックになります。
しかし、レシーバーが表示されるメソッド名やその他の接頭辞の場合、文法でキーワードを許可するのは簡単です。 JavaScriptはそれを行います。
ecma-262 の文法例
.Netでは、言語ごとに異なるキーワードのセットがあります。たとえば、これは、C#で記述されたライブラリがVB.NETで予約されている識別子を使用できることを意味します。したがって、VB.NETからそのようなライブラリを使用するには、キーワードを識別子として使用する方法が必要です。
各言語は、それを行うために異なる構文を使用します。
c#では、@
:
@keyword
vB.NETでは、括弧で囲みます。
[keyword]
f#では、二重バッククォートで囲みます。
``keyword``
標準的な方法はないと思います。
「次のトークンがネイティブなキーワードである場合にのみ、純粋なキーワードである」などのルールを実装するいくつかのレクサートリックが見られることがあります。
場合によっては、文法担当者は、状況によっては、すべてまたは一部のキーワードを曖昧さを導入せずに識別子として解釈できるという事実を利用することがあります。