字句構造Lexical structure

ProgramsPrograms

C#プログラム1 つまたは複数から成るソース ファイル正式と呼ばれる、コンパイル単位(コンパイル単位)。A C# program consists of one or more source files, known formally as compilation units (Compilation units). ソース ファイルは、Unicode 文字の順序付けられたシーケンスです。A source file is an ordered sequence of Unicode characters. ソース ファイルでは、ファイル システムで、ファイルと一対一の対応を通常されましたが、この対応は必要ありません。Source files typically have a one-to-one correspondence with files in a file system, but this correspondence is not required. 最大の移植性、お勧めファイル システム内のファイルが、utf-8 でエンコードするエンコーディングします。For maximal portability, it is recommended that files in a file system be encoded with the UTF-8 encoding.

概念的には、3 つの手順を使用してプログラムのコンパイルします。Conceptually speaking, a program is compiled using three steps:

  1. 変換ファイルを特定の文字のレパートリーとエンコード体系を Unicode 文字のシーケンスに変換します。Transformation, which converts a file from a particular character repertoire and encoding scheme into a sequence of Unicode characters.
  2. 字句解析、トークンのストリームに Unicode の入力文字のストリームを変換します。Lexical analysis, which translates a stream of Unicode input characters into a stream of tokens.
  3. 構文解析、実行可能コードにトークンのストリームを変換します。Syntactic analysis, which translates the stream of tokens into executable code.

文法Grammars

この仕様は、c# プログラミング言語の 2 つの文法を使用して構文を表示します。This specification presents the syntax of the C# programming language using two grammars. 字句文法(字句文法) 行終端記号、空白、コメント、トークン、およびプリプロセッサ ディレクティブに Unicode 文字を結合する方法を定義します。The lexical grammar (Lexical grammar) defines how Unicode characters are combined to form line terminators, white space, comments, tokens, and pre-processing directives. 構文文法(構文文法) 字句文法に起因するトークンを組み合わせて c# プログラムを構成する方法を定義します。The syntactic grammar (Syntactic grammar) defines how the tokens resulting from the lexical grammar are combined to form C# programs.

文法の表記Grammar notation

字句および構文の文法は、ANTLR 文章校正ツールの表記を使用してバッカスナウア記法の形式で表示されます。The lexical and syntactic grammars are presented in Backus-Naur form using the notation of the ANTLR grammar tool.

字句文法Lexical grammar

C# の構文文法を示した字句解析トークン、およびプリプロセッサ ディレクティブします。The lexical grammar of C# is presented in Lexical analysis, Tokens, and Pre-processing directives. 字句文法の終端記号は、Unicode 文字セットの文字と構文の文法では、トークンを構成する文字を集計する方法を指定します (トークン)、空白文字 (空白)、コメント (コメント)、およびプリプロセッサ ディレクティブ (プリプロセッサ ディレクティブ)。The terminal symbols of the lexical grammar are the characters of the Unicode character set, and the lexical grammar specifies how characters are combined to form tokens (Tokens), white space (White space), comments (Comments), and pre-processing directives (Pre-processing directives).

C# プログラムですべてのソース ファイルに準拠する必要があります、入力字句文法の実稼働 (字句解析)。Every source file in a C# program must conform to the input production of the lexical grammar (Lexical analysis).

構文文法Syntactic grammar

この章に従います付録では、c# の構文の文法が表示されます。The syntactic grammar of C# is presented in the chapters and appendices that follow this chapter. 構文文法のターミナル シンボルは、構文の文法で定義されているトークンと構文の文法では、トークンを組み合わせて c# プログラムを構成する方法を指定します。The terminal symbols of the syntactic grammar are the tokens defined by the lexical grammar, and the syntactic grammar specifies how tokens are combined to form C# programs.

すべてのソース ファイルで、C#にプログラムが準拠する必要があります、 compilation_unit構文文法の実稼働 (コンパイル単位)。Every source file in a C# program must conform to the compilation_unit production of the syntactic grammar (Compilation units).

字句解析Lexical analysis

入力運用 c# ソース ファイルの構文構造を定義します。The input production defines the lexical structure of a C# source file. C# プログラムでは、各ソース ファイルは、この構文の文法の実稼働環境に従う必要があります。Each source file in a C# program must conform to this lexical grammar production.

input
    : input_section?
    ;

input_section
    : input_section_part+
    ;

input_section_part
    : input_element* new_line
    | pp_directive
    ;

input_element
    : whitespace
    | comment
    | token
    ;

5 つの基本的な要素は、c# ソース ファイルの構文構造を構成します。行ターミネータ (行ターミネータ)、空白文字 (空白)、コメント (コメント)、トークン (トークン)、およびプリプロセッサ ディレクティブ (プリプロセッサ ディレクティブ)。Five basic elements make up the lexical structure of a C# source file: Line terminators (Line terminators), white space (White space), comments (Comments), tokens (Tokens), and pre-processing directives (Pre-processing directives). これらの基本要素のトークンだけが、c# プログラムの構文の文法で重要です (構文文法)。Of these basic elements, only tokens are significant in the syntactic grammar of a C# program (Syntactic grammar).

C# ソース ファイルの構文の処理、構文分析への入力になるトークンのシーケンスに、ファイルを減らすことで構成されます。The lexical processing of a C# source file consists of reducing the file into a sequence of tokens which becomes the input to the syntactic analysis. トークンを区切る行の終端記号、空白文字、およびコメントを使用できるとプリプロセッサ ディレクティブがスキップされるソース ファイルのセクションが発生することができますが、それ以外の場合これらの構文要素ありません影響 c# プログラムの構文構造に。Line terminators, white space, and comments can serve to separate tokens, and pre-processing directives can cause sections of the source file to be skipped, but otherwise these lexical elements have no impact on the syntactic structure of a C# program.

補間文字列リテラルの場合 (リテラル文字列の補間) 1 つのトークンの字句解析、によって最初に生成されるが、繰り返しの字句解析を対象となるいくつかの入力要素に分割されますまで、すべての補間文字列リテラルが解決されました。In the case of interpolated string literals (Interpolated string literals) a single token is initially produced by lexical analysis, but is broken up into several input elements which are repeatedly subjected to lexical analysis until all interpolated string literals have been resolved. 結果として得られるトークンは、構文分析への入力として使用します。The resulting tokens then serve as input to the syntactic analysis.

いくつかの構文文法には、ソース ファイル内の文字のシーケンスが一致すると、最も長い可能な構文要素を形成字句処理は常にします。When several lexical grammar productions match a sequence of characters in a source file, the lexical processing always forms the longest possible lexical element. たとえば、文字シーケンス//が、その構文の要素が 1 つを超えるため、単一行コメントの始まりとして処理される/トークンです。For example, the character sequence // is processed as the beginning of a single-line comment because that lexical element is longer than a single / token.

行ターミネータLine terminators

行ターミネータは、c# ソース ファイルの文字を行に分割します。Line terminators divide the characters of a C# source file into lines.

new_line
    : '<Carriage return character (U+000D)>'
    | '<Line feed character (U+000A)>'
    | '<Carriage return character (U+000D) followed by line feed character (U+000A)>'
    | '<Next line character (U+0085)>'
    | '<Line separator character (U+2028)>'
    | '<Paragraph separator character (U+2029)>'
    ;

ソースとの互換性をコード ファイルの終わりのマーカーを追加している編集ツールとのシーケンスとして正しく表示するファイルをソースを有効にするには、行を終了した、c# プログラムでソース ファイルごとに順番に、次の変換が適用します。For compatibility with source code editing tools that add end-of-file markers, and to enable a source file to be viewed as a sequence of properly terminated lines, the following transformations are applied, in order, to every source file in a C# program:

  • ソース ファイルの最後の文字がコントロール Z の文字 (U+001A)、この文字を削除します。If the last character of the source file is a Control-Z character (U+001A), this character is deleted.
  • 復帰文字 (U+000D) とそのソース ファイルが空でない場合は、ソース ファイルの最後の文字は、キャリッジ リターンがない場合は、ソース ファイルの末尾に追加されます (U+000D)、ライン フィード (U+000A)、行区切り記号 (U+2028)、または段落区切り記号 (U+2029)。A carriage-return character (U+000D) is added to the end of the source file if that source file is non-empty and if the last character of the source file is not a carriage return (U+000D), a line feed (U+000A), a line separator (U+2028), or a paragraph separator (U+2029).

コメントComments

コメントの 2 つの形式がサポートされています。 単一行コメントおよび区切り記号付きのコメント。Two forms of comments are supported: single-line comments and delimited comments. 単一行コメント最初の文字//およびソース行の末尾に拡張します。Single-line comments start with the characters // and extend to the end of the source line. コメントの区切り最初の文字/*文字で終わる*/します。Delimited comments start with the characters /* and end with the characters */. 区切り記号付きコメントは、複数行にわたる可能性があります。Delimited comments may span multiple lines.

comment
    : single_line_comment
    | delimited_comment
    ;

single_line_comment
    : '//' input_character*
    ;

input_character
    : '<Any Unicode character except a new_line_character>'
    ;

new_line_character
    : '<Carriage return character (U+000D)>'
    | '<Line feed character (U+000A)>'
    | '<Next line character (U+0085)>'
    | '<Line separator character (U+2028)>'
    | '<Paragraph separator character (U+2029)>'
    ;

delimited_comment
    : '/*' delimited_comment_section* asterisk+ '/'
    ;

delimited_comment_section
    : '/'
    | asterisk* not_slash_or_asterisk
    ;

asterisk
    : '*'
    ;

not_slash_or_asterisk
    : '<Any Unicode character except / or *>'
    ;

コメントを入れ子にしないでください。Comments do not nest. 文字シーケンス/**/内で特別な意味があるない、//コメント、および文字のシーケンス///*区切られたコメントの内部で特別な意味があるありません。The character sequences /* and */ have no special meaning within a // comment, and the character sequences // and /* have no special meaning within a delimited comment.

コメントは、文字と文字列リテラル内では処理されません。Comments are not processed within character and string literals.

例では、The example

/* Hello, world program
   This program writes "hello, world" to the console
*/
class Hello
{
    static void Main() {
        System.Console.WriteLine("hello, world");
    }
}

区切り記号付きのコメントが含まれています。includes a delimited comment.

例では、The example

// Hello, world program
// This program writes "hello, world" to the console
//
class Hello // any name will do for this class
{
    static void Main() { // this method must be named "Main"
        System.Console.WriteLine("hello, world");
    }
}

いくつかの単一行コメントを示しています。shows several single-line comments.

空白White space

空白文字は Unicode クラス (Zs の空白文字を含む) を使用して任意の文字だけでなく、水平タブ文字、垂直タブ文字、およびフォーム フィード文字として定義されます。White space is defined as any character with Unicode class Zs (which includes the space character) as well as the horizontal tab character, the vertical tab character, and the form feed character.

whitespace
    : '<Any character with Unicode class Zs>'
    | '<Horizontal tab character (U+0009)>'
    | '<Vertical tab character (U+000B)>'
    | '<Form feed character (U+000C)>'
    ;

トークンTokens

トークンのいくつかの種類があります。 識別子、キーワード、リテラル、演算子、および区切り記号。There are several kinds of tokens: identifiers, keywords, literals, operators, and punctuators. 空白とコメントは、トークンが、トークンの区切り記号として。White space and comments are not tokens, though they act as separators for tokens.

token
    : identifier
    | keyword
    | integer_literal
    | real_literal
    | character_literal
    | string_literal
    | interpolated_string_literal
    | operator_or_punctuator
    ;

Unicode 文字のエスケープ シーケンスUnicode character escape sequences

Unicode 文字のエスケープ シーケンスは、Unicode 文字を表します。A Unicode character escape sequence represents a Unicode character. Unicode 文字のエスケープ シーケンスは、識別子で処理されます (識別子)、文字リテラル (文字リテラル)、および通常の文字列リテラル (リテラル文字列).Unicode character escape sequences are processed in identifiers (Identifiers), character literals (Character literals), and regular string literals (String literals). Unicode 文字のエスケープは、その他の場所 (たとえば、演算子などの区切り記号、またはキーワードを形成する) では処理されません。A Unicode character escape is not processed in any other location (for example, to form an operator, punctuator, or keyword).

unicode_escape_sequence
    : '\\u' hex_digit hex_digit hex_digit hex_digit
    | '\\U' hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit
    ;

Unicode エスケープ シーケンスは、16 進数の数値以下で構成される 1 つの Unicode 文字を表す、"\u「または」\U"文字です。A Unicode escape sequence represents the single Unicode character formed by the hexadecimal number following the "\u" or "\U" characters. C# 文字と文字列値では Unicode コード ポイントの 16 ビットのエンコーディングを使用するため、u+10000 U + 10 ffff の範囲の Unicode 文字は文字リテラルでは許可されていませんし、Unicode サロゲート ペアを使用して、文字列リテラルで表されます。Since C# uses a 16-bit encoding of Unicode code points in characters and string values, a Unicode character in the range U+10000 to U+10FFFF is not permitted in a character literal and is represented using a Unicode surrogate pair in a string literal. 0x10ffff まで上記のコード ポイントを使用した Unicode 文字がサポートされていません。Unicode characters with code points above 0x10FFFF are not supported.

複数の翻訳は行われません。Multiple translations are not performed. たとえば、文字列リテラル"\u005Cu005C「は等価である」\u005C「なく」\"。For instance, the string literal "\u005Cu005C" is equivalent to "\u005C" rather than "\". Unicode 値\u005C文字"\"。The Unicode value \u005C is the character "\".

例では、The example

class Class1
{
    static void Test(bool \u0066) {
        char c = '\u0066';
        if (\u0066)
            System.Console.WriteLine(c.ToString());
    }        
}

いくつか示されて\u0066、これは、文字のエスケープ シーケンス"f"。shows several uses of \u0066, which is the escape sequence for the letter "f". プログラムと同じです。The program is equivalent to

class Class1
{
    static void Test(bool f) {
        char c = 'f';
        if (f)
            System.Console.WriteLine(c.ToString());
    }        
}

識別子Identifiers

このセクションで指定された識別子の規則は、点を除いて、アンダー スコアが Unicode のエスケープ シーケンスは、(同様に、C プログラミング言語で従来は) 初期文字として許可されると正確に、Unicode Standard Annex 31 で、推奨される対応します。識別子で許可されていると、"@"を識別子として使用するキーワードを有効にプレフィックスとして使用できる文字。The rules for identifiers given in this section correspond exactly to those recommended by the Unicode Standard Annex 31, except that underscore is allowed as an initial character (as is traditional in the C programming language), Unicode escape sequences are permitted in identifiers, and the "@" character is allowed as a prefix to enable keywords to be used as identifiers.

identifier
    : available_identifier
    | '@' identifier_or_keyword
    ;

available_identifier
    : '<An identifier_or_keyword that is not a keyword>'
    ;

identifier_or_keyword
    : identifier_start_character identifier_part_character*
    ;

identifier_start_character
    : letter_character
    | '_'
    ;

identifier_part_character
    : letter_character
    | decimal_digit_character
    | connecting_character
    | combining_character
    | formatting_character
    ;

letter_character
    : '<A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl>'
    | '<A unicode_escape_sequence representing a character of classes Lu, Ll, Lt, Lm, Lo, or Nl>'
    ;

combining_character
    : '<A Unicode character of classes Mn or Mc>'
    | '<A unicode_escape_sequence representing a character of classes Mn or Mc>'
    ;

decimal_digit_character
    : '<A Unicode character of the class Nd>'
    | '<A unicode_escape_sequence representing a character of the class Nd>'
    ;

connecting_character
    : '<A Unicode character of the class Pc>'
    | '<A unicode_escape_sequence representing a character of the class Pc>'
    ;

formatting_character
    : '<A Unicode character of the class Cf>'
    | '<A unicode_escape_sequence representing a character of the class Cf>'
    ;

上記で説明した Unicode 文字クラスについては、Unicode 標準、バージョン 3.0、4.5 のセクションを参照してください。For information on the Unicode character classes mentioned above, see The Unicode Standard, Version 3.0, section 4.5.

有効な識別子の例として、"identifier1「,」_identifier2"、および"@if"。Examples of valid identifiers include "identifier1", "_identifier2", and "@if".

準拠したプログラムで識別子は、Unicode Standard Annex 15 で定義されている Unicode 正規形 C で定義された正規の形式でなければなりません。An identifier in a conforming program must be in the canonical format defined by Unicode Normalization Form C, as defined by Unicode Standard Annex 15. 正規形 C ではなく識別子が検出されたときの動作は実装で定義されます。ただし、診断は必要ありません。The behavior when encountering an identifier not in Normalization Form C is implementation-defined; however, a diagnostic is not required.

プレフィックス"@"他のプログラミング言語と接続した場合に便利です、識別子としてのキーワードの使用を有効にします。The prefix "@" enables the use of keywords as identifiers, which is useful when interfacing with other programming languages. 文字@他の言語では、プレフィックスなしの通常の識別子として認識されるため、識別子の一部ではありません。The character @ is not actually part of the identifier, so the identifier might be seen in other languages as a normal identifier, without the prefix. 識別子、@プレフィックスと呼ばれる、逐語的識別子します。An identifier with an @ prefix is called a verbatim identifier. 使用、@キーワードではない識別子のプレフィックスは許可されていますが、スタイルの問題としてお勧めします。Use of the @ prefix for identifiers that are not keywords is permitted, but strongly discouraged as a matter of style.

例:The example:

class @class
{
    public static void @static(bool @bool) {
        if (@bool)
            System.Console.WriteLine("true");
        else
            System.Console.WriteLine("false");
    }    
}

class Class1
{
    static void M() {
        cl\u0061ss.st\u0061tic(true);
    }
}

という名前のクラスを定義します。"classという名前の静的メソッド"と"static"をという名前のパラメーターを受け取る"bool"。defines a class named "class" with a static method named "static" that takes a parameter named "bool". Unicode エスケープするため、トークンのキーワードでは使用できませんに注意してください"cl\u0061ss「識別子、およびと同じ識別子が」@class"。Note that since Unicode escapes are not permitted in keywords, the token "cl\u0061ss" is an identifier, and is the same identifier as "@class".

順序で、次の変換が適用される結果が同一の場合は、2 つの識別子は同じで考えられます。Two identifiers are considered the same if they are identical after the following transformations are applied, in order:

  • プレフィックス"@"を使用する場合は、削除されます。The prefix "@", if used, is removed.
  • unicode_escape_sequence対応する Unicode 文字に変換されます。Each unicode_escape_sequence is transformed into its corresponding Unicode character.
  • すべてformatting_characters に削除されます。Any formatting_characters are removed.

識別子を含む 2 つの連続するアンダー スコア文字 (U+005F) 実装で使用するために予約されています。Identifiers containing two consecutive underscore characters (U+005F) are reserved for use by the implementation. たとえば、実装は、2 つのアンダー スコアで始まる拡張のキーワード。For example, an implementation might provide extended keywords that begin with two underscores.

キーワードKeywords

Aキーワード識別子のような文字シーケンスは、予約されていると、前に付けない限り識別子として使用できませんが、@文字。A keyword is an identifier-like sequence of characters that is reserved, and cannot be used as an identifier except when prefaced by the @ character.

keyword
    : 'abstract' | 'as'       | 'base'       | 'bool'      | 'break'
    | 'byte'     | 'case'     | 'catch'      | 'char'      | 'checked'
    | 'class'    | 'const'    | 'continue'   | 'decimal'   | 'default'
    | 'delegate' | 'do'       | 'double'     | 'else'      | 'enum'
    | 'event'    | 'explicit' | 'extern'     | 'false'     | 'finally'
    | 'fixed'    | 'float'    | 'for'        | 'foreach'   | 'goto'
    | 'if'       | 'implicit' | 'in'         | 'int'       | 'interface'
    | 'internal' | 'is'       | 'lock'       | 'long'      | 'namespace'
    | 'new'      | 'null'     | 'object'     | 'operator'  | 'out'
    | 'override' | 'params'   | 'private'    | 'protected' | 'public'
    | 'readonly' | 'ref'      | 'return'     | 'sbyte'     | 'sealed'
    | 'short'    | 'sizeof'   | 'stackalloc' | 'static'    | 'string'
    | 'struct'   | 'switch'   | 'this'       | 'throw'     | 'true'
    | 'try'      | 'typeof'   | 'uint'       | 'ulong'     | 'unchecked'
    | 'unsafe'   | 'ushort'   | 'using'      | 'virtual'   | 'void'
    | 'volatile' | 'while'
    ;

文法でいくつかの場所では、特定の識別子は、特殊な意味があるが、キーワードではありません。In some places in the grammar, specific identifiers have special meaning, but are not keywords. このような識別子は、「コンテキスト キーワード」とも呼ばれます。Such identifiers are sometimes referred to as "contextual keywords". プロパティの宣言内など、"get「と」set"識別子が特別な意味を持ちます (アクセサー)。For example, within a property declaration, the "get" and "set" identifiers have special meaning (Accessors). 以外の識別子getまたはset識別子としてこれらの単語の使用量がこのような使用が競合しないようにこれらの場所では許可されません。An identifier other than get or set is never permitted in these locations, so this use does not conflict with a use of these words as identifiers. それ以外の場合によっては、識別子と"var"暗黙的に型指定されたローカル変数宣言で (ローカル変数宣言)、コンテキスト キーワードは宣言された名前と競合することです。In other cases, such as with the identifier "var" in implicitly typed local variable declarations (Local variable declarations), a contextual keyword can conflict with declared names. このような場合は、宣言された名前は、コンテキスト キーワードとして識別子の使用に優先します。In such cases, the declared name takes precedence over the use of the identifier as a contextual keyword.

リテラルLiterals

Aリテラル値のソース コードの表現です。A literal is a source code representation of a value.

literal
    : boolean_literal
    | integer_literal
    | real_literal
    | character_literal
    | string_literal
    | null_literal
    ;

ブール型リテラルBoolean literals

2 つのブール型リテラル値がある:truefalseします。There are two boolean literal values: true and false.

boolean_literal
    : 'true'
    | 'false'
    ;

型をboolean_literalboolします。The type of a boolean_literal is bool.

整数リテラルInteger literals

整数リテラルの型の値を記述に使用intuintlong、およびulongします。Integer literals are used to write values of types int, uint, long, and ulong. 整数リテラルがある 2 つの可能な形式: 10 進数と 16 進数。Integer literals have two possible forms: decimal and hexadecimal.

integer_literal
    : decimal_integer_literal
    | hexadecimal_integer_literal
    ;

decimal_integer_literal
    : decimal_digit+ integer_type_suffix?
    ;

decimal_digit
    : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    ;

integer_type_suffix
    : 'U' | 'u' | 'L' | 'l' | 'UL' | 'Ul' | 'uL' | 'ul' | 'LU' | 'Lu' | 'lU' | 'lu'
    ;

hexadecimal_integer_literal
    : '0x' hex_digit+ integer_type_suffix?
    | '0X' hex_digit+ integer_type_suffix?
    ;

hex_digit
    : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
    | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';

整数リテラルの型は、次のように決定されます。The type of an integer literal is determined as follows:

  • リテラルにサフィックスがあるない場合は、最初の値を表す型。 intuintlongulongします。If the literal has no suffix, it has the first of these types in which its value can be represented: int, uint, long, ulong.
  • リテラルが付いている場合Uまたはu、最初の値を表す型があります: uintulongします。If the literal is suffixed by U or u, it has the first of these types in which its value can be represented: uint, ulong.
  • リテラルが付いている場合Lまたはl、最初の値を表す型があります: longulongします。If the literal is suffixed by L or l, it has the first of these types in which its value can be represented: long, ulong.
  • リテラルが付いている場合ULUluLulLULulU、またはlu、型であるulongします。If the literal is suffixed by UL, Ul, uL, ul, LU, Lu, lU, or lu, it is of type ulong.

範囲の整数リテラルで表される値が、ulong入力すると、コンパイル時エラーが発生します。If the value represented by an integer literal is outside the range of the ulong type, a compile-time error occurs.

スタイルの問題、としては推奨される"L「の代わりに使用する」l"型のリテラルの書き込み時にlong文字を混同しないでくださいであるため、"l数字の"と"1"。As a matter of style, it is suggested that "L" be used instead of "l" when writing literals of type long, since it is easy to confuse the letter "l" with the digit "1".

値の最小値を許可するようにintlong、10 進整数リテラルとして記述する、次の 2 つの規則が存在する値。To permit the smallest possible int and long values to be written as decimal integer literals, the following two rules exist:

  • ときに、 decimal_integer_literal 2147483648 値 (2 ^31) および no integer_type_suffix単項マイナス演算子トークンの直後に続くトークンとして表示されます (単項マイナス演算子)、結果は型の定数int値-2147483648 (-2 ^31)。When a decimal_integer_literal with the value 2147483648 (2^31) and no integer_type_suffix appears as the token immediately following a unary minus operator token (Unary minus operator), the result is a constant of type int with the value -2147483648 (-2^31). その他のすべての状況でこのようなdecimal_integer_literalの種類はuintします。In all other situations, such a decimal_integer_literal is of type uint.
  • ときに、 decimal_integer_literal 9223372036854775808 値 (2 ^63) および no integer_type_suffixまたはinteger_type_suffix Lまたはl単項マイナス演算子トークンの直後に続くトークンとして表示されます (単項マイナス演算子)、結果は型の定数long値-9223372036854775808 (-2 ^63)。When a decimal_integer_literal with the value 9223372036854775808 (2^63) and no integer_type_suffix or the integer_type_suffix L or l appears as the token immediately following a unary minus operator token (Unary minus operator), the result is a constant of type long with the value -9223372036854775808 (-2^63). その他のすべての状況でこのようなdecimal_integer_literalの種類はulongします。In all other situations, such a decimal_integer_literal is of type ulong.

実際のリテラルReal literals

実際のリテラルの型の値を記述に使用floatdouble、およびdecimalします。Real literals are used to write values of types float, double, and decimal.

real_literal
    : decimal_digit+ '.' decimal_digit+ exponent_part? real_type_suffix?
    | '.' decimal_digit+ exponent_part? real_type_suffix?
    | decimal_digit+ exponent_part real_type_suffix?
    | decimal_digit+ real_type_suffix
    ;

exponent_part
    : 'e' sign? decimal_digit+
    | 'E' sign? decimal_digit+
    ;

sign
    : '+'
    | '-'
    ;

real_type_suffix
    : 'F' | 'f' | 'D' | 'd' | 'M' | 'm'
    ;

ない場合はreal_type_suffixを指定すると、実際のリテラルの型はdoubleします。If no real_type_suffix is specified, the type of the real literal is double. それ以外の場合、実数のリテラルの種類を次のように決定実数型のサフィックス。Otherwise, the real type suffix determines the type of the real literal, as follows:

  • 実数のリテラル サフィックスFまたはfの種類はfloatします。A real literal suffixed by F or f is of type float. たとえば、リテラルは、 1f1.5f1e10f123.456Fすべて型floatFor example, the literals 1f, 1.5f, 1e10f, and 123.456F are all of type float.
  • 実数のリテラル サフィックスDまたはdの種類はdoubleします。A real literal suffixed by D or d is of type double. たとえば、リテラルは、 1d1.5d1e10d123.456Dすべて型doubleFor example, the literals 1d, 1.5d, 1e10d, and 123.456D are all of type double.
  • 実数のリテラル サフィックスMまたはmの種類はdecimalします。A real literal suffixed by M or m is of type decimal. たとえば、リテラルは、 1m1.5m1e10m123.456Mすべて型decimalFor example, the literals 1m, 1.5m, 1e10m, and 123.456M are all of type decimal. このリテラルに変換をdecimal、正確な値を取得し、必要に応じてを使用して最も近い表現可能な値に丸め値銀行型丸めが (10 進数型)。This literal is converted to a decimal value by taking the exact value, and, if necessary, rounding to the nearest representable value using banker's rounding (The decimal type). 値が丸められますか、値が 0 (この後者の場合、記号と小数点 0 になります) しない限り、リテラルのスケールが保持されます。Any scale apparent in the literal is preserved unless the value is rounded or the value is zero (in which latter case the sign and scale will be 0). そのため、リテラル2.900m記号と小数点以下のフォームに解析0、係数2900、有効桁数と小数点3します。Hence, the literal 2.900m will be parsed to form the decimal with sign 0, coefficient 2900, and scale 3.

指定されたリテラルは、示された型で表すことができない、コンパイル時エラーが発生します。If the specified literal cannot be represented in the indicated type, a compile-time error occurs.

型の実数のリテラル値floatまたはdoubleIEEE を使用して決定されます"round を最も近い"モードです。The value of a real literal of type float or double is determined by using the IEEE "round to nearest" mode.

実数のリテラルに桁が常に必要である、小数点より後に注意してください。Note that in a real literal, decimal digits are always required after the decimal point. たとえば、1.3Fが実数値リテラルですが1.Fはありません。For example, 1.3F is a real literal but 1.F is not.

文字リテラルCharacter literals

文字リテラルが単一の文字を表し、通常ように、引用符で囲まれた文字で構成されます'a'します。A character literal represents a single character, and usually consists of a character in quotes, as in 'a'.

メモ:ANTLR 文法の表記では、次を混乱に!Note: The ANTLR grammar notation makes the following confusing! 記述するときに、ANTLR\'の単一引用符現時点では'します。In ANTLR, when you write \' it stands for a single quote '. 記述するときと\\現時点では、1 つの円記号の\します。And when you write \\ it stands for a single backslash \. そのため、単一引用符、文字、単一引用符で始まるリテラル文字の最初の規則を意味します。Therefore the first rule for a character literal means it starts with a single quote, then a character, then a single quote. 11 個の可能な単純なエスケープ シーケンスと\'\"\\\0\a\b\f\n\r\t\v.And the eleven possible simple escape sequences are \', \", \\, \0, \a, \b, \f, \n, \r, \t, \v.

character_literal
    : '\'' character '\''
    ;

character
    : single_character
    | simple_escape_sequence
    | hexadecimal_escape_sequence
    | unicode_escape_sequence
    ;

single_character
    : '<Any character except \' (U+0027), \\ (U+005C), and new_line_character>'
    ;

simple_escape_sequence
    : '\\\'' | '\\"' | '\\\\' | '\\0' | '\\a' | '\\b' | '\\f' | '\\n' | '\\r' | '\\t' | '\\v'
    ;

hexadecimal_escape_sequence
    : '\\x' hex_digit hex_digit? hex_digit? hex_digit?;

円記号に続く文字 (\) で、文字、次の文字のいずれかを指定する必要があります: '"\0ab, f, n, r, t, u, U, x, v.A character that follows a backslash character (\) in a character must be one of the following characters: ', ", \, 0, a, b, f, n, r, t, u, U, x, v. それ以外の場合は、コンパイル時のエラーが発生します。Otherwise, a compile-time error occurs.

16 進数のエスケープ シーケンスは、16 進数の数値以下で構成された値を 1 つの Unicode 文字を表します"\x"。A hexadecimal escape sequence represents a single Unicode character, with the value formed by the hexadecimal number following "\x".

リテラル文字で表される値がより大きいかどうかU+FFFFコンパイル時エラーが発生します。If the value represented by a character literal is greater than U+FFFF, a compile-time error occurs.

Unicode 文字のエスケープ シーケンス (Unicode 文字のエスケープ シーケンス) リテラル文字の範囲で指定する必要がありますU+0000U+FFFFします。A Unicode character escape sequence (Unicode character escape sequences) in a character literal must be in the range U+0000 to U+FFFF.

次の表で説明されているように、単純なエスケープ シーケンスは、Unicode 文字のエンコーディングを表します。A simple escape sequence represents a Unicode character encoding, as described in the table below.

エスケープ シーケンスEscape sequence 文字の名前Character name Unicode エンコーディングUnicode encoding
\' 単一引用符Single quote 0x0027
\" 二重引用符Double quote 0x0022
\\ 円記号Backslash 0x005C
\0 NullNull 0x0000
\a 警告Alert 0x0007
\b バックスペースBackspace 0x0008
\f フォーム フィードForm feed 0x000C
\n 改行New line 0x000A
\r キャリッジ リターンCarriage return 0x000D
\t 水平タブHorizontal tab 0x0009
\v 垂直タブVertical tab 0x000B

型をcharacter_literalcharします。The type of a character_literal is char.

文字列リテラルString literals

C# では、文字列リテラルの 2 つの形式:標準文字列リテラルverbatim 文字列リテラルします。C# supports two forms of string literals: regular string literals and verbatim string literals.

標準リテラル文字列としての二重引用符で囲まれた 0 個以上の文字から成る"hello"、両方の単純なエスケープ シーケンスを含めることができ、(など\tでタブ文字)、16 進数と Unicode のエスケープ シーケンス。A regular string literal consists of zero or more characters enclosed in double quotes, as in "hello", and may include both simple escape sequences (such as \t for the tab character), and hexadecimal and Unicode escape sequences.

Verbatim 文字列リテラルから成る、@文字の後に二重引用符文字、0 個以上の文字と終わりの二重引用符文字。A verbatim string literal consists of an @ character followed by a double-quote character, zero or more characters, and a closing double-quote character. 簡単な例は、@"hello"します。A simple example is @"hello". 逐語的文字列リテラル、区切り記号の間の文字は、そのまま解釈されている唯一の例外をquote_escape_sequenceします。In a verbatim string literal, the characters between the delimiters are interpreted verbatim, the only exception being a quote_escape_sequence. 具体的には、単純なエスケープ シーケンス、および 16 進数、および Unicode のエスケープ シーケンスは、verbatim 文字列リテラルでは処理されません。In particular, simple escape sequences, and hexadecimal and Unicode escape sequences are not processed in verbatim string literals. Verbatim 文字列リテラルは、複数行にわたる可能性があります。A verbatim string literal may span multiple lines.

string_literal
    : regular_string_literal
    | verbatim_string_literal
    ;

regular_string_literal
    : '"' regular_string_literal_character* '"'
    ;

regular_string_literal_character
    : single_regular_string_literal_character
    | simple_escape_sequence
    | hexadecimal_escape_sequence
    | unicode_escape_sequence
    ;

single_regular_string_literal_character
    : '<Any character except " (U+0022), \\ (U+005C), and new_line_character>'
    ;

verbatim_string_literal
    : '@"' verbatim_string_literal_character* '"'
    ;

verbatim_string_literal_character
    : single_verbatim_string_literal_character
    | quote_escape_sequence
    ;

single_verbatim_string_literal_character
    : '<any character except ">'
    ;

quote_escape_sequence
    : '""'
    ;

円記号に続く文字 (\) で、 regular_string_literal_character 、次の文字のいずれかを指定する必要があります: '"\0a, b, f, n, r, t, u, U, x, v.A character that follows a backslash character (\) in a regular_string_literal_character must be one of the following characters: ', ", \, 0, a, b, f, n, r, t, u, U, x, v. それ以外の場合は、コンパイル時のエラーが発生します。Otherwise, a compile-time error occurs.

例では、The example

string a = "hello, world";                   // hello, world
string b = @"hello, world";                  // hello, world

string c = "hello \t world";                 // hello      world
string d = @"hello \t world";                // hello \t world

string e = "Joe said \"Hello\" to me";       // Joe said "Hello" to me
string f = @"Joe said ""Hello"" to me";      // Joe said "Hello" to me

string g = "\\\\server\\share\\file.txt";    // \\server\share\file.txt
string h = @"\\server\share\file.txt";       // \\server\share\file.txt

string i = "one\r\ntwo\r\nthree";
string j = @"one
two
three";

さまざまな文字列リテラルを示しています。shows a variety of string literals. 最後の文字列リテラル、 j、逐語的文字列リテラルは複数の行にまたがるには。The last string literal, j, is a verbatim string literal that spans multiple lines. 改行文字などの空白を含む、引用符の間の文字をそのまま維持されます。The characters between the quotation marks, including white space such as new line characters, are preserved verbatim.

16 進数のエスケープ シーケンスは、文字列リテラル、16 進数が変数を持つことができますので"\x123"16 進値 123 の 1 つの文字が含まれています。Since a hexadecimal escape sequence can have a variable number of hex digits, the string literal "\x123" contains a single character with hex value 123. を 16 進値 12 が 3 文字が続く文字を含む文字列を作成する 1 つ記述"\x00123"または"\x12" + "3"代わりにします。To create a string containing the character with hex value 12 followed by the character 3, one could write "\x00123" or "\x12" + "3" instead.

型をstring_literalstringします。The type of a string_literal is string.

各文字列リテラルは、新しい文字列インスタンスで必ずしも発生するされません。Each string literal does not necessarily result in a new string instance. 2 つ以上の文字列リテラルが場合に応じて、文字列の等値演算子と同じです (文字列等値演算子) これらの文字列リテラルは、同じ文字列インスタンスを参照してください、同じプログラムで表示されます。When two or more string literals that are equivalent according to the string equality operator (String equality operators) appear in the same program, these string literals refer to the same string instance. によって生成された出力インスタンス、For instance, the output produced by

class Test
{
    static void Main() {
        object a = "hello";
        object b = "hello";
        System.Console.WriteLine(a == b);
    }
}

Trueのため、2 つのリテラルは、同じ文字列インスタンスを参照してください。is True because the two literals refer to the same string instance.

補間文字列リテラルInterpolated string literals

補間文字列リテラルは、文字列リテラルに似ていますで区切られた穴が含まれて{}式に、発生することができます。Interpolated string literals are similar to string literals, but contain holes delimited by { and }, wherein expressions can occur. 実行時に穴が発生した位置に文字列に代入されるテキストがフォームが目的に設定された式を評価します。At runtime, the expressions are evaluated with the purpose of having their textual forms substituted into the string at the place where the hole occurs. 構文とセマンティクスの文字列補間がセクションで説明されている (文字列補間)。The syntax and semantics of string interpolation are described in section (Interpolated strings).

文字列リテラルのように、補間文字列リテラルは正規表現または逐語的のいずれかを指定できます。Like string literals, interpolated string literals can be either regular or verbatim. 挿入の標準文字列リテラルを区切ることによって$""、補間の逐語的文字列リテラルを区切ることによって、$@""します。Interpolated regular string literals are delimited by $" and ", and interpolated verbatim string literals are delimited by $@" and ".

など、他のリテラル、補間文字列リテラルの字句解析は、最初に以下の文法に従って、1 つのトークンの結果します。Like other literals, lexical analysis of an interpolated string literal initially results in a single token, as per the grammar below. ただし、構文解析前に、補間文字列リテラルの 1 つのトークンはセキュリティ ホールを囲む文字列の部品用のいくつかのトークンに分割、ホールで発生している入力の要素がもう一度分析構文。However, before syntactic analysis, the single token of an interpolated string literal is broken into several tokens for the parts of the string enclosing the holes, and the input elements occurring in the holes are lexically analysed again. これにより、処理するには、修正は、構文の解析を処理するためのトークンのシーケンスに最終的につながる場合、構文的に補間文字列リテラルよりさらに生成可能性があります。This may in turn produce more interpolated string literals to be processed, but, if lexically correct, will eventually lead to a sequence of tokens for syntactic analysis to process.

interpolated_string_literal
    : '$' interpolated_regular_string_literal
    | '$' interpolated_verbatim_string_literal
    ;

interpolated_regular_string_literal
    : interpolated_regular_string_whole
    | interpolated_regular_string_start  interpolated_regular_string_literal_body interpolated_regular_string_end
    ;

interpolated_regular_string_literal_body
    : regular_balanced_text
    | interpolated_regular_string_literal_body interpolated_regular_string_mid regular_balanced_text
    ;

interpolated_regular_string_whole
    : '"' interpolated_regular_string_character* '"'
    ;

interpolated_regular_string_start
    : '"' interpolated_regular_string_character* '{'
    ;

interpolated_regular_string_mid
    : interpolation_format? '}' interpolated_regular_string_characters_after_brace? '{'
    ;

interpolated_regular_string_end
    : interpolation_format? '}' interpolated_regular_string_characters_after_brace? '"'
    ;

interpolated_regular_string_characters_after_brace
    : interpolated_regular_string_character_no_brace
    | interpolated_regular_string_characters_after_brace interpolated_regular_string_character
    ;

interpolated_regular_string_character
    : single_interpolated_regular_string_character
    | simple_escape_sequence
    | hexadecimal_escape_sequence
    | unicode_escape_sequence
    | open_brace_escape_sequence
    | close_brace_escape_sequence
    ;

interpolated_regular_string_character_no_brace
    : '<Any interpolated_regular_string_character except close_brace_escape_sequence and any hexadecimal_escape_sequence or unicode_escape_sequence designating } (U+007D)>'
    ;

single_interpolated_regular_string_character
    : '<Any character except \" (U+0022), \\ (U+005C), { (U+007B), } (U+007D), and new_line_character>'
    ;

open_brace_escape_sequence
    : '{{'
    ;

close_brace_escape_sequence
    : '}}'
    ;
    
regular_balanced_text
    : regular_balanced_text_part+
    ;

regular_balanced_text_part
    : single_regular_balanced_text_character
    | delimited_comment
    | '@' identifier_or_keyword
    | string_literal
    | interpolated_string_literal
    | '(' regular_balanced_text ')'
    | '[' regular_balanced_text ']'
    | '{' regular_balanced_text '}'
    ;
    
single_regular_balanced_text_character
    : '<Any character except / (U+002F), @ (U+0040), \" (U+0022), $ (U+0024), ( (U+0028), ) (U+0029), [ (U+005B), ] (U+005D), { (U+007B), } (U+007D) and new_line_character>'
    | '</ (U+002F), if not directly followed by / (U+002F) or * (U+002A)>'
    ;
    
interpolation_format
    : interpolation_format_character+
    ;
    
interpolation_format_character
    : '<Any character except \" (U+0022), : (U+003A), { (U+007B) and } (U+007D)>'
    ;
    
interpolated_verbatim_string_literal
    : interpolated_verbatim_string_whole
    | interpolated_verbatim_string_start interpolated_verbatim_string_literal_body interpolated_verbatim_string_end
    ;

interpolated_verbatim_string_literal_body
    : verbatim_balanced_text
    | interpolated_verbatim_string_literal_body interpolated_verbatim_string_mid verbatim_balanced_text
    ;
    
interpolated_verbatim_string_whole
    : '@"' interpolated_verbatim_string_character* '"'
    ;
    
interpolated_verbatim_string_start
    : '@"' interpolated_verbatim_string_character* '{'
    ;
    
interpolated_verbatim_string_mid
    : interpolation_format? '}' interpolated_verbatim_string_characters_after_brace? '{'
    ;
    
interpolated_verbatim_string_end
    : interpolation_format? '}' interpolated_verbatim_string_characters_after_brace? '"'
    ;
    
interpolated_verbatim_string_characters_after_brace
    : interpolated_verbatim_string_character_no_brace
    | interpolated_verbatim_string_characters_after_brace interpolated_verbatim_string_character
    ;
    
interpolated_verbatim_string_character
    : single_interpolated_verbatim_string_character
    | quote_escape_sequence
    | open_brace_escape_sequence
    | close_brace_escape_sequence
    ;
    
interpolated_verbatim_string_character_no_brace
    : '<Any interpolated_verbatim_string_character except close_brace_escape_sequence>'
    ;
    
single_interpolated_verbatim_string_character
    : '<Any character except \" (U+0022), { (U+007B) and } (U+007D)>'
    ;
    
verbatim_balanced_text
    : verbatim_balanced_text_part+
    ;

verbatim_balanced_text_part
    : single_verbatim_balanced_text_character
    | comment
    | '@' identifier_or_keyword
    | string_literal
    | interpolated_string_literal
    | '(' verbatim_balanced_text ')'
    | '[' verbatim_balanced_text ']'
    | '{' verbatim_balanced_text '}'
    ;
    
single_verbatim_balanced_text_character
    : '<Any character except / (U+002F), @ (U+0040), \" (U+0022), $ (U+0024), ( (U+0028), ) (U+0029), [ (U+005B), ] (U+005D), { (U+007B) and } (U+007D)>'
    | '</ (U+002F), if not directly followed by / (U+002F) or * (U+002A)>'
    ;

Interpolated_string_literalトークンが複数のトークンおよびその他の入力要素を次のように内に見つかった位置の順序で解釈、 interpolated_string_literal:An interpolated_string_literal token is reinterpreted as multiple tokens and other input elements as follows, in order of occurrence in the interpolated_string_literal:

  • 次の出現回数が個別の個々 のトークンとして再解釈: 先頭$記号、 interpolated_regular_string_wholeinterpolated_regular_string_startinterpolated_regular_string_midinterpolated_regular_string_endinterpolated_verbatim_string_wholeinterpolated_verbatim_string_startinterpolated_verbatim_string_midinterpolated_verbatim_string_endします。Occurrences of the following are reinterpreted as separate individual tokens: the leading $ sign, interpolated_regular_string_whole, interpolated_regular_string_start, interpolated_regular_string_mid, interpolated_regular_string_end, interpolated_verbatim_string_whole, interpolated_verbatim_string_start, interpolated_verbatim_string_mid and interpolated_verbatim_string_end.
  • 出現regular_balanced_textverbatim_balanced_textとしてこれらの間は再処理するinput_section (字句解析) と、入力要素の結果として得られるシーケンスとして解釈されます。Occurrences of regular_balanced_text and verbatim_balanced_text between these are reprocessed as an input_section (Lexical analysis) and are reinterpreted as the resulting sequence of input elements. 加え、補間文字列リテラル トークンに含まれます。These may in turn include interpolated string literal tokens to be reinterpreted.

構文解析にトークンを再結合、 interpolated_string_expression (文字列補間)。Syntactic analysis will recombine the tokens into an interpolated_string_expression (Interpolated strings).

TODO の例Examples TODO

Null リテラルThe null literal

null_literal
    : 'null'
    ;

Null_literal参照型または null 許容型に暗黙的に変換できます。The null_literal can be implicitly converted to a reference type or nullable type.

演算子と区切り記号Operators and punctuators

これには演算子と区切り記号のいくつかの種類があります。There are several kinds of operators and punctuators. 演算子は、1 つまたは複数のオペランドに関連する操作を記述する式で使用されます。Operators are used in expressions to describe operations involving one or more operands. たとえば、式a + bを使用して、 + 2 つのオペランドを追加する演算子abします。For example, the expression a + b uses the + operator to add the two operands a and b. 区切り記号はグループ化および分離することです。Punctuators are for grouping and separating.

operator_or_punctuator
    : '{'  | '}'  | '['  | ']'  | '('   | ')'  | '.'  | ','  | ':'  | ';'
    | '+'  | '-'  | '*'  | '/'  | '%'   | '&'  | '|'  | '^'  | '!'  | '~'
    | '='  | '<'  | '>'  | '?'  | '??'  | '::' | '++' | '--' | '&&' | '||'
    | '->' | '==' | '!=' | '<=' | '>='  | '+=' | '-=' | '*=' | '/=' | '%='
    | '&=' | '|=' | '^=' | '<<' | '<<=' | '=>'
    ;

right_shift
    : '>>'
    ;

right_shift_assignment
    : '>>='
    ;

垂直のバーで、 right_shiftright_shift_assignment生産を使用するには、構文の文法では、任意の種類の文字がないのでは、他の生産とは異なり (あって空白文字) は、トークンの間に許可します。The vertical bar in the right_shift and right_shift_assignment productions are used to indicate that, unlike other productions in the syntactic grammar, no characters of any kind (not even whitespace) are allowed between the tokens. それらの生産がの適切な処理を有効にするために特別に扱われますtype_parameter_lists (パラメーター入力)。These productions are treated specially in order to enable the correct handling of type_parameter_lists (Type parameters).

プリプロセッサ ディレクティブPre-processing directives

プリプロセッサ ディレクティブは、条件付きでソース ファイル、レポートのエラーおよび警告の条件のセクションをスキップして、ソース コードの異なる領域を区切るために機能を提供します。The pre-processing directives provide the ability to conditionally skip sections of source files, to report error and warning conditions, and to delineate distinct regions of source code. 「プリプロセッサ ディレクティブ」という用語は、C および C++ のプログラミング言語との整合性のみ使用されます。The term "pre-processing directives" is used only for consistency with the C and C++ programming languages. C# の場合は、別の前処理ステップ; はありません。プリプロセッサ ディレクティブは、字句解析フェーズの一環として処理されます。In C#, there is no separate pre-processing step; pre-processing directives are processed as part of the lexical analysis phase.

pp_directive
    : pp_declaration
    | pp_conditional
    | pp_line
    | pp_diagnostic
    | pp_region
    | pp_pragma
    ;

次のプリプロセッサ ディレクティブを使用できます。The following pre-processing directives are available:

プリプロセッサ ディレクティブが常にソース コードの別の行を占有し、常に始まり、#文字と前処理ディレクティブ名。A pre-processing directive always occupies a separate line of source code and always begins with a # character and a pre-processing directive name. 空白文字が前に発生する、#文字、および、#文字とディレクティブの名前。White space may occur before the # character and between the # character and the directive name.

含むソース行、 #define#undef#if#elif#else#endif#line、または#endregionディレクティブは、単一行コメントとなる可能性があります。A source line containing a #define, #undef, #if, #elif, #else, #endif, #line, or #endregion directive may end with a single-line comment. コメントの区切り (、/* */形式のコメント) は、プリプロセッサ ディレクティブを含むソース行では許可されていません。Delimited comments (the /* */ style of comments) are not permitted on source lines containing pre-processing directives.

プリプロセッサ ディレクティブは、トークンは、c# の構文の文法の一部ではないです。Pre-processing directives are not tokens and are not part of the syntactic grammar of C#. ただし、プリプロセッサ ディレクティブまたはトークンのシーケンスを除外するために使用して、その方法でに影響する c# プログラムの意味。However, pre-processing directives can be used to include or exclude sequences of tokens and can in that way affect the meaning of a C# program. たとえば、コンパイルされると、プログラム。For example, when compiled, the program:

#define A
#undef B

class C
{
#if A
    void F() {}
#else
    void G() {}
#endif

#if B
    void H() {}
#else
    void I() {}
#endif
}

プログラムとトークンの正確な順序で結果:results in the exact same sequence of tokens as the program:

class C
{
    void F() {}
    void I() {}
}

つまり、2 つのプログラムは、構文的には、まったく異なる構文的には同じです。Thus, whereas lexically, the two programs are quite different, syntactically, they are identical.

[条件付きコンパイル シンボル]Conditional compilation symbols

条件付きコンパイルの機能、 #if#elif#else、および#endifディレクティブは処理前の式によって制御されます (プリプロセス式)条件付きコンパイル シンボルを選択します。The conditional compilation functionality provided by the #if, #elif, #else, and #endif directives is controlled through pre-processing expressions (Pre-processing expressions) and conditional compilation symbols.

conditional_symbol
    : '<Any identifier_or_keyword except true or false>'
    ;

条件付きコンパイル シンボルが 2 つの状態:定義または未定義します。A conditional compilation symbol has two possible states: defined or undefined. ソース ファイルの構文の処理の先頭には、(コマンド ライン コンパイラ オプション) などの外部機構によって明示的に定義されている場合を除き、条件付きコンパイル シンボルは定義されません。At the beginning of the lexical processing of a source file, a conditional compilation symbol is undefined unless it has been explicitly defined by an external mechanism (such as a command-line compiler option). ときに、#defineディレクティブが処理されると、そのソース ファイルでそのディレクティブで、条件付きコンパイル シンボルが定義されています。When a #define directive is processed, the conditional compilation symbol named in that directive becomes defined in that source file. シンボルは削除されるまで、#undef同じシンボルが処理されるか、ソース ファイルの末尾に到達するまでディレクティブ。The symbol remains defined until an #undef directive for that same symbol is processed, or until the end of the source file is reached. この意味は#define#undef同じプログラム内で他のソース ファイルに 1 つのソース ファイルでディレクティブの影響がありません。An implication of this is that #define and #undef directives in one source file have no effect on other source files in the same program.

処理前の式で参照されている、定義済みの条件付きコンパイル シンボルがブール値true、ブール値であり、未定義の条件付きコンパイル シンボルfalseします。When referenced in a pre-processing expression, a defined conditional compilation symbol has the boolean value true, and an undefined conditional compilation symbol has the boolean value false. 要件はありません、条件付きコンパイル シンボルを明示的に宣言処理前の式で参照される前にします。There is no requirement that conditional compilation symbols be explicitly declared before they are referenced in pre-processing expressions. 宣言されていないシンボルが代わりに、単に定義されていませんし、値があるためfalseします。Instead, undeclared symbols are simply undefined and thus have the value false.

条件付きコンパイル シンボルの名前空間と区別され、c# プログラムの他のすべての名前付きエンティティから分離します。The name space for conditional compilation symbols is distinct and separate from all other named entities in a C# program. 条件付きコンパイル シンボルでのみ参照できます#define#undefディレクティブと、処理前の式で。Conditional compilation symbols can only be referenced in #define and #undef directives and in pre-processing expressions.

処理前の式Pre-processing expressions

処理前の式が発生することが#if#elifディレクティブ。Pre-processing expressions can occur in #if and #elif directives. 演算子!==!=&&||処理前の式では許可されてあり、グループ化かっこを使用できます。The operators !, ==, !=, && and || are permitted in pre-processing expressions, and parentheses may be used for grouping.

pp_expression
    : whitespace? pp_or_expression whitespace?
    ;

pp_or_expression
    : pp_and_expression
    | pp_or_expression whitespace? '||' whitespace? pp_and_expression
    ;

pp_and_expression
    : pp_equality_expression
    | pp_and_expression whitespace? '&&' whitespace? pp_equality_expression
    ;

pp_equality_expression
    : pp_unary_expression
    | pp_equality_expression whitespace? '==' whitespace? pp_unary_expression
    | pp_equality_expression whitespace? '!=' whitespace? pp_unary_expression
    ;

pp_unary_expression
    : pp_primary_expression
    | '!' whitespace? pp_unary_expression
    ;

pp_primary_expression
    : 'true'
    | 'false'
    | conditional_symbol
    | '(' whitespace? pp_expression whitespace? ')'
    ;

処理前の式で参照されている、定義済みの条件付きコンパイル シンボルがブール値true、ブール値であり、未定義の条件付きコンパイル シンボルfalseします。When referenced in a pre-processing expression, a defined conditional compilation symbol has the boolean value true, and an undefined conditional compilation symbol has the boolean value false.

常に、処理前の式の評価は、ブール値を生成します。Evaluation of a pre-processing expression always yields a boolean value. 処理前の式の評価の規則は、定数式の場合と同じ (定数式)、参照できるのみ、ユーザー定義エンティティは、条件付きコンパイル シンボル.The rules of evaluation for a pre-processing expression are the same as those for a constant expression (Constant expressions), except that the only user-defined entities that can be referenced are conditional compilation symbols.

宣言ディレクティブDeclaration directives

宣言のディレクティブは、定義または条件付きコンパイル シンボルを未定義に使用されます。The declaration directives are used to define or undefine conditional compilation symbols.

pp_declaration
    : whitespace? '#' whitespace? 'define' whitespace conditional_symbol pp_new_line
    | whitespace? '#' whitespace? 'undef' whitespace conditional_symbol pp_new_line
    ;

pp_new_line
    : whitespace? single_line_comment? new_line
    ;

処理、#defineディレクティブにより、定義する特定の条件付きコンパイル シンボル ディレクティブに続くソース行から開始します。The processing of a #define directive causes the given conditional compilation symbol to become defined, starting with the source line that follows the directive. 同様の処理、#undefディレクティブとディレクティブを次のソース行で始まる、未定義になる特定の条件付きコンパイル シンボル。Likewise, the processing of an #undef directive causes the given conditional compilation symbol to become undefined, starting with the source line that follows the directive.

すべて#define#undefソース ファイルでディレクティブは、最初の前に出現する必要がありますトークン(トークン) は、ソース ファイルでそれ以外の場合、コンパイル時エラーが発生します。Any #define and #undef directives in a source file must occur before the first token (Tokens) in the source file; otherwise a compile-time error occurs. 直感的な用語で#define#undefディレクティブがソース ファイルの「実際のコード」を付ける必要があります。In intuitive terms, #define and #undef directives must precede any "real code" in the source file.

例:The example:

#define Enterprise

#if Professional || Enterprise
    #define Advanced
#endif

namespace Megacorp.Data
{
    #if Advanced
    class PivotTable {...}
    #endif
}

有効ではため、#defineディレクティブの前に、最初のトークン (、namespaceキーワード) でソース ファイル。is valid because the #define directives precede the first token (the namespace keyword) in the source file.

次の例では、コンパイル時エラーのため、結果を#define実際のコードします。The following example results in a compile-time error because a #define follows real code:

#define A
namespace N
{
    #define B
    #if B
    class Class1 {}
    #endif
}

A#define既に定義されている、すべての介在が存在せず、条件付きコンパイル シンボルを定義することがあります#undefそのシンボル。A #define may define a conditional compilation symbol that is already defined, without there being any intervening #undef for that symbol. 次の例は、条件付きコンパイル シンボルを定義します。Aし、もう一度定義します。The example below defines a conditional compilation symbol A and then defines it again.

#define A
#define A

A#undef可能性があります""条件付きコンパイル シンボルを未定義に定義されていません。A #undef may "undefine" a conditional compilation symbol that is not defined. 次の例は、条件付きコンパイル シンボルを定義します。Aしてし、未定義に 2 回ですが、2 つ目#undef、影響を与えません有効であります。The example below defines a conditional compilation symbol A and then undefines it twice; although the second #undef has no effect, it is still valid.

#define A
#undef A
#undef A

条件付きコンパイル ディレクティブConditional compilation directives

条件付きコンパイル ディレクティブは、条件付きで含めるか、ソース ファイルの部分を除外に使用されます。The conditional compilation directives are used to conditionally include or exclude portions of a source file.

pp_conditional
    : pp_if_section pp_elif_section* pp_else_section? pp_endif
    ;

pp_if_section
    : whitespace? '#' whitespace? 'if' whitespace pp_expression pp_new_line conditional_section?
    ;

pp_elif_section
    : whitespace? '#' whitespace? 'elif' whitespace pp_expression pp_new_line conditional_section?
    ;

pp_else_section:
    | whitespace? '#' whitespace? 'else' pp_new_line conditional_section?
    ;

pp_endif
    : whitespace? '#' whitespace? 'endif' pp_new_line
    ;

conditional_section
    : input_section
    | skipped_section
    ;

skipped_section
    : skipped_section_part+
    ;

skipped_section_part
    : skipped_characters? new_line
    | pp_directive
    ;

skipped_characters
    : whitespace? not_number_sign input_character*
    ;

not_number_sign
    : '<Any input_character except #>'
    ;

、の順でから成るセットとして示されるように、構文、条件付きコンパイル ディレクティブを書き込む必要があります、#ifディレクティブ、0 個以上#elifディレクティブ、0 または 1 個#elseディレクティブ、および#endifディレクティブ。As indicated by the syntax, conditional compilation directives must be written as sets consisting of, in order, an #if directive, zero or more #elif directives, zero or one #else directive, and an #endif directive. ディレクティブの間、ソース コードの条件付きセクションです。Between the directives are conditional sections of source code. 各セクションは、直前のディレクティブによって制御されます。Each section is controlled by the immediately preceding directive. 条件付きセクションを含めることができます自体入れ子になった条件付きコンパイル ディレクティブ提供、これらのディレクティブは、完全なセットを形成します。A conditional section may itself contain nested conditional compilation directives provided these directives form complete sets.

A pp_conditionalの格納されている 1 つだけ選択conditional_sectionの通常の構文処理。A pp_conditional selects at most one of the contained conditional_sections for normal lexical processing:

  • Pp_expressionの s、#if#elifディレクティブは、1 つを生成するまで順序で評価されますtrueします。The pp_expressions of the #if and #elif directives are evaluated in order until one yields true. 式の結果が場合trueconditional_sectionの対応するディレクティブが選択されています。If an expression yields true, the conditional_section of the corresponding directive is selected.
  • すべてpp_expressions yield false、場合に、#elseディレクティブが存在する、 conditional_section#elseディレクティブが選択されています。If all pp_expressions yield false, and if an #else directive is present, the conditional_section of the #else directive is selected.
  • それ以外の場合、no conditional_sectionが選択されています。Otherwise, no conditional_section is selected.

選択したconditional_sectionとして、通常、いずれかが処理される場合、 input_section: セクションに含まれるソース コードは、構文、文法に従う必要があります元のトークンが生成されます。セクションのコードプリプロセッサ ディレクティブのセクションでは、所定の影響を与えます。The selected conditional_section, if any, is processed as a normal input_section: the source code contained in the section must adhere to the lexical grammar; tokens are generated from the source code in the section; and pre-processing directives in the section have the prescribed effects.

残りのconditional_sectionとして処理されているのであれば、 skipped_sectionプリプロセッサ ディレクティブを除く: %s、セクション内のソース コードが必要に準拠していない、字句文法; なしセクションで、ソース コードからトークンが生成されます。プリプロセッサ ディレクティブのセクションでは構文的に正しくなければなりませんが、それ以外の場合は処理されません。The remaining conditional_sections, if any, are processed as skipped_sections: except for pre-processing directives, the source code in the section need not adhere to the lexical grammar; no tokens are generated from the source code in the section; and pre-processing directives in the section must be lexically correct but are not otherwise processed. 内で、 conditional_sectionとして処理されますが、 skipped_sectionを入れ子になったconditional_sections (に含まれている入れ子になった#if...#endif#region.#endregionを構築します) として処理されます。 またskipped_section秒。Within a conditional_section that is being processed as a skipped_section, any nested conditional_sections (contained in nested #if...#endif and #region...#endregion constructs) are also processed as skipped_sections.

次の例は、条件付きコンパイル ディレクティブを入れ子を示しています。The following example illustrates how conditional compilation directives can nest:

#define Debug       // Debugging on
#undef Trace        // Tracing off

class PurchaseTransaction
{
    void Commit() {
        #if Debug
            CheckConsistency();
            #if Trace
                WriteToLog(this.ToString());
            #endif
        #endif
        CommitHelper();
    }
}

プリプロセッサ ディレクティブを除くスキップされたソース コードが字句解析の対象です。Except for pre-processing directives, skipped source code is not subject to lexical analysis. たとえば、未終了のコメントに関係なく有効では、次の#elseセクション。For example, the following is valid despite the unterminated comment in the #else section:

#define Debug        // Debugging on

class PurchaseTransaction
{
    void Commit() {
        #if Debug
            CheckConsistency();
        #else
            /* Do something else
        #endif
    }
}

ただし、プリプロセッサ ディレクティブがソース コードのセクションをスキップしたであっても正しい構文的に必要なことに注意してください。Note, however, that pre-processing directives are required to be lexically correct even in skipped sections of source code.

複数行の入力要素内に存在する場合、プリプロセッサ ディレクティブは処理されません。Pre-processing directives are not processed when they appear inside multi-line input elements. たとえば、プログラムします。For example, the program:

class Hello
{
    static void Main() {
        System.Console.WriteLine(@"hello, 
#if Debug
        world
#else
        Nebraska
#endif
        ");
    }
}

出力結果:results in the output:

hello,
#if Debug
        world
#else
        Nebraska
#endif

評価に特有の場合、プリプロセッサ ディレクティブの処理は、セットが依存可能性があります、 pp_expressionします。In peculiar cases, the set of pre-processing directives that is processed might depend on the evaluation of the pp_expression. 例:The example:

#if X
    /*
#else
    /* */ class Q { }
#endif

常に同じトークン ストリームを生成します (class Q { }) かどうかに関係なく、Xが定義されています。always produces the same token stream (class Q { }), regardless of whether or not X is defined. 場合Xが定義するには、ディレクティブだけが処理されます#if#endif複数行のコメントにしている。If X is defined, the only processed directives are #if and #endif, due to the multi-line comment. 場合Xが未定義の場合、3 つのディレクティブ (#if#else#endif) ディレクティブのセットの一部であります。If X is undefined, then three directives (#if, #else, #endif) are part of the directive set.

診断ディレクティブDiagnostic directives

診断のディレクティブを使用すると、エラー メッセージとその他のコンパイル時エラーと警告と同じ方法で報告される警告メッセージを明示的に生成します。The diagnostic directives are used to explicitly generate error and warning messages that are reported in the same way as other compile-time errors and warnings.

pp_diagnostic
    : whitespace? '#' whitespace? 'error' pp_message
    | whitespace? '#' whitespace? 'warning' pp_message
    ;

pp_message
    : new_line
    | whitespace input_character* new_line
    ;

例:The example:

#warning Code review needed before check-in

#if Debug && Retail
    #error A build can't be both debug and retail
#endif

class Test {...}

常に (「コード レビューでは、チェックイン前に必要な」)、警告を生成し、コンパイル時エラーを生成します (「をビルドすることはできませんデバッグし、製品版」) 場合、条件付きシンボルDebugRetailの両方が定義されています。always produces a warning ("Code review needed before check-in"), and produces a compile-time error ("A build can't be both debug and retail") if the conditional symbols Debug and Retail are both defined. なお、 pp_message任意のテキストを含めることができます。 具体的には、含める必要はありません、適切な形式のトークン、word で単一引用符で示すようにcan'tします。Note that a pp_message can contain arbitrary text; specifically, it need not contain well-formed tokens, as shown by the single quote in the word can't.

領域ディレクティブRegion directives

領域ディレクティブを使用して、ソース コードの領域を明示的にマークします。The region directives are used to explicitly mark regions of source code.

pp_region
    : pp_start_region conditional_section? pp_end_region
    ;

pp_start_region
    : whitespace? '#' whitespace? 'region' pp_message
    ;

pp_end_region
    : whitespace? '#' whitespace? 'endregion' pp_message
    ;

領域に接続されているセマンティックな意味がありません。リージョンが使用するため、プログラマや自動化ツール ソース コードのセクションをマークします。No semantic meaning is attached to a region; regions are intended for use by the programmer or by automated tools to mark a section of source code. 指定されたメッセージ、#regionまたは#endregionディレクティブはセマンティックな意味は無効同様に、領域を識別するためにのみ機能します。The message specified in a #region or #endregion directive likewise has no semantic meaning; it merely serves to identify the region. 一致する#region#endregionディレクティブが異なる場合がありますがpp_message秒。Matching #region and #endregion directives may have different pp_messages.

領域の処理の構文:The lexical processing of a region:

#region
...
#endregion

フォームの条件付きコンパイル ディレクティブの構文の処理に正確に対応しています。corresponds exactly to the lexical processing of a conditional compilation directive of the form:

#if true
...
#endif

行ディレクティブLine directives

行ディレクティブは、行番号とが報告された警告やエラーなどの出力で、コンパイラによって、呼び出し元情報属性で使用されるソース ファイル名を変更するために使用可能性があります (呼び出し元情報属性)。Line directives may be used to alter the line numbers and source file names that are reported by the compiler in output such as warnings and errors, and that are used by caller info attributes (Caller info attributes).

行ディレクティブは、他のテキスト入力からの c# ソース コードを生成するメタ プログラミング ツールで最もよく使用されます。Line directives are most commonly used in meta-programming tools that generate C# source code from some other text input.

pp_line
    : whitespace? '#' whitespace? 'line' whitespace line_indicator pp_new_line
    ;

line_indicator
    : decimal_digit+ whitespace file_name
    | decimal_digit+
    | 'default'
    | 'hidden'
    ;

file_name
    : '"' file_name_character+ '"'
    ;

file_name_character
    : '<Any input_character except ">'
    ;

ない場合#lineディレクティブが存在する、コンパイラは実際の行番号とその出力でのソース ファイル名を報告します。When no #line directives are present, the compiler reports true line numbers and source file names in its output. 処理するときに、#lineディレクティブが含まれる、 line_indicatorでないdefaultコンパイラは、特定の行番号 (および指定した場合、ファイル名) を持つものとしてディレクティブの後の行を扱います。When processing a #line directive that includes a line_indicator that is not default, the compiler treats the line after the directive as having the given line number (and file name, if specified).

A#line defaultディレクティブ上のすべての #line ディレクティブの効果を反転させます。A #line default directive reverses the effect of all preceding #line directives. コンパイラが正確にない場合、後続の行の場合は true。 行情報を報告#lineディレクティブは処理されている必要がありました。The compiler reports true line information for subsequent lines, precisely as if no #line directives had been processed.

A#line hiddenディレクティブには、ファイルへの影響はありませんし、行番号のエラー報告は、メッセージが、ソース レベルのデバッグは影響します。A #line hidden directive has no effect on the file and line numbers reported in error messages, but does affect source level debugging. すべての行の間でのデバッグ時に、#line hiddenディレクティブとそれに続く#lineディレクティブ (でない#line hidden) 行番号情報があるありません。When debugging, all lines between a #line hidden directive and the subsequent #line directive (that is not #line hidden) have no line number information. デバッガーでコードをステップ実行時に、これらの行はすべてスキップされます。When stepping through code in the debugger, these lines will be skipped entirely.

なお、 file_nameされるエスケープ文字は処理されません通常の文字列リテラルと異なります、"\"文字が単純に内での通常のバック スラッシュ文字を指定、 file_nameNote that a file_name differs from a regular string literal in that escape characters are not processed; the "\" character simply designates an ordinary backslash character within a file_name.

プラグマ ディレクティブPragma directives

#pragmaプリプロセッサ ディレクティブを使用すると、コンパイラにコンテキスト情報を指定します。The #pragma preprocessing directive is used to specify optional contextual information to the compiler. 情報の指定、#pragmaディレクティブには、プログラムのセマンティクスは変わりません。The information supplied in a #pragma directive will never change program semantics.

pp_pragma
    : whitespace? '#' whitespace? 'pragma' whitespace pragma_body pp_new_line
    ;

pragma_body
    : pragma_warning_body
    ;

C# では#pragmaコンパイラの警告を制御するためのディレクティブ。C# provides #pragma directives to control compiler warnings. 将来のバージョンの言語は、追加で含めることができます#pragmaディレクティブ。Future versions of the language may include additional #pragma directives. 他の c# コンパイラとの相互運用のために、Microsoft c# コンパイラを発行しません不明なコンパイル エラー#pragmaディレクティブはこのようなディレクティブは、ただし警告を生成します。To ensure interoperability with other C# compilers, the Microsoft C# compiler does not issue compilation errors for unknown #pragma directives; such directives do however generate warnings.

Pragma 警告Pragma warning

#pragma warningディレクティブを使用して無効にするか、またはすべてを復元する、またはそれ以降のプログラム テキストのコンパイル中にメッセージを特定の警告のセット。The #pragma warning directive is used to disable or restore all or a particular set of warning messages during compilation of the subsequent program text.

pragma_warning_body
    : 'warning' whitespace warning_action
    | 'warning' whitespace warning_action whitespace warning_list
    ;

warning_action
    : 'disable'
    | 'restore'
    ;

warning_list
    : decimal_digit+ (whitespace? ',' whitespace? decimal_digit+)*
    ;

A#pragma warning警告の一覧の指定を省略するディレクティブがすべての警告に影響します。A #pragma warning directive that omits the warning list affects all warnings. A#pragma warningディレクティブが含まれています、警告の一覧の一覧で指定されている警告のみに影響を与えます。A #pragma warning directive the includes a warning list affects only those warnings that are specified in the list.

A#pragma warning disableディレクティブ無効にします。 すべてまたは指定した警告のセット。A #pragma warning disable directive disables all or the given set of warnings.

A#pragma warning restoreディレクティブ復元のすべてまたは特定の一連のコンパイル単位の先頭で有効にされた状態に警告します。A #pragma warning restore directive restores all or the given set of warnings to the state that was in effect at the beginning of the compilation unit. 特定の警告が外部で無効になっている場合、 #pragma warning restore (すべてのかどうか、または特定の警告) 警告を再度有効にはありません。Note that if a particular warning was disabled externally, a #pragma warning restore (whether for all or the specific warning) will not re-enable that warning.

次の例は、の使用を示しています。 #pragma warning 、警告を一時的に無効にする場合に報告廃止 Microsoft c# コンパイラから警告番号を使用して、メンバーが参照します。The following example shows use of #pragma warning to temporarily disable the warning reported when obsoleted members are referenced, using the warning number from the Microsoft C# compiler.

using System;

class Program
{
    [Obsolete]
    static void Foo() {}

    static void Main() {
#pragma warning disable 612
    Foo();
#pragma warning restore 612
    }
}