コンピュータプログラミング言語において、識別子とは、言語のエンティティに名前を付ける字句(シンボルとも呼ばれるが、シンボルプリミティブデータ型とは混同してはならない)のことである。識別子が示す可能性のあるエンティティの種類には、変数、データ型、ラベル、サブルーチン、モジュールなどがある。
どの文字シーケンスが識別子を構成するかは、言語の字句文法に依存します。一般的なルールは、英数字シーケンスで、アンダースコアも許可されます(一部の言語では _ は許可されません)。また、数値で始まってはならないという条件があります(整数リテラルとの混同を避けることで字句解析を簡素化するため)。つまり、 は許可されますが、は許可されません。これは、CやC++、Python、その他多くの言語の初期バージョンで使用されていた定義です。これらの言語の後のバージョン、および他の多くの現代的な言語では、識別子でより多くのUnicode文字がサポートされています。ただし、一般的な制限として、空白文字と言語演算子は許可されません。これにより、トークン化が自由形式で文脈に依存しないものになるため、トークン化が簡素化されます。たとえば、バイナリ演算として使用されるために識別子で を禁止すると、 と は同じようにトークン化されますが、 が許可されると、 は加算ではなく識別子になります。識別子内の空白は特に問題となります。なぜなら、識別子にスペースが許可されている場合、 のような節が、 を識別子として有効となり、これをトークン化するには、 が if 節の条件内にあるという句のコンテキストが必要になるからです。ただし、ALGOL 68や一部の ALGOL バリアントなど、識別子にスペースを許可する言語もあります。たとえば、次の文は有効です。これは、 として入力できます(キーワードは太字で表され、具体的にはストロッピングによって表現されます)。ALGOL では、キーワードが構文的に区別されているため衝突や曖昧さのリスクがなく、行再構築フェーズでスペースが削除され、ソースがスキャナレス解析によって処理されるため、字句解析がコンテキスト依存になる可能性があるため、これが可能でした。foo, foo1, foo_bar, _foo1foo+a+ba + ba+bif rainy day then 1rainy dayreal half pi;.real. half pi;
ほとんどの言語では、一部の文字シーケンスは識別子の字句形式を持ちますが、キーワードとして知られています。たとえば、はif節のキーワードとしてよく使われますが、字句的にはや とif同じ形式、つまり文字のシーケンスです。この重複はさまざまな方法で処理できます。識別子として禁止することでトークン化と構文解析が簡素化され、その場合は予約語になります。また、両方とも許可され、ストロッピングなどの他の方法で区別される場合もあります。あるいは、キーワードシーケンスを識別子として許可し、その意味をコンテキストから決定する場合もあり、その場合はコンテキスト依存の字句解析器が必要です。キーワード以外のものも予約語(識別子として禁止)にすることができ、特に将来的に単語がキーワードになる可能性がある場合に備えて、前方互換性のためにそうすることがあります。PL /1などの一部の言語では、この区別は明確ではありません。igfoo
プログラム内における識別子のスコープ、つまりアクセス可能性は、ローカルまたはグローバルのいずれかになります。グローバル識別子は関数の外で宣言され、プログラム全体で使用できます。ローカル識別子は特定の関数内で宣言され、その関数内でのみ使用できます。[ 1 ]
コンパイラを使用するプログラミング言語の実装では、識別子はコンパイル時のみに存在するエンティティであることが多い。つまり、実行時には、コンパイルされたプログラムにはテキスト形式の識別子トークンではなく、メモリのアドレスとオフセットへの参照が含まれる(これらのメモリのアドレスまたはオフセットは、コンパイラによって各識別子に割り当てられる)。
リフレクションをサポートする言語(例えば、インタプリタやインクリメンタルコンパイラを用いたソースコードの対話型評価など)では、識別子も実行時エンティティであり、場合によっては自由に操作および評価できる第一級オブジェクトとして扱われます。Lispでは、これらはシンボルと呼ばれます。
コンパイラやインタプリタは通常、実際に使用される文字シーケンスに基づいて識別子に意味的な意味を割り当てません。ただし、例外もあります。例えば、次のようになります。
Go言語など一部の言語では、識別子の一意性はスペルと可視性に基づいている。[ 2 ]