
C# 程序(PRogram)由至少一個源文件(source files)組成,其正式稱謂為編譯單元(compilation units)[1]。每個源文件都是有序的 Unicode 字符序列。源文件通常與文件系統內的相應文件具有一對一關系,但這種相關性并非必須因素。為盡最大可能確保可移植性,推薦文件系統中的文件編碼為 UTF-8 編碼規范。
從理論上來說,程序編譯由三步驟組成:
本規范提出兩種文法(grammars)來表示 C# 的語法(syntax)。詞法文法(lexical grammar)定義了 Unicode 字符是如何組成行結束符(line terminators)、空白(white space)、注釋(comments)、標記(tokens)和預處理指令(pre-processing directives)的,關于這一方面請詳見本規范第二章第 2.2 節;句法文法(syntactic grammar)則定義了標記符號是如何從詞法文法(lexical grammar)轉換而來并組成了 C# 程序的,這個則將在本規范第二章第 2.3 節詳述。
詞法文法(lexical grammar)和句法文法(syntactic grammar)均通過使用文法產生式(grammar productions)來表示。每個文法產生式都定義了一個非終結符號(non-terminal symbol)及其可能的擴展(擴展由非終結符號與終結符號組成)。在文法產生式中,非終結符號被用斜體顯示,而終結符號則使用等寬字體(fixed-width font)來表示。
詞法產生式的第一行被定義為非終結符號的名稱,而后緊跟著一個冒號 :。緊接這一行之后的連續幾行相同縮進風格的是由非終結符號或終結符號構成的擴展。比方說下面這個詞法產生式:

上面定義的這個 while-statement 包含了一個 while 標記,之后分別跟著 (、boolean-expression、) 和 embedded-statement。當有超過一個非終結符擴展時,將它們交替列出,每一個擴展獨占一行。如下面這個詞法產生式:

上面定義的 statement-list 包含了一個 statement 以及一個緊隨其后的 statement-list。換句話說,所定義的 statement-list 是遞歸的,它包含至少一個 statement。
下標 “opt” 被用于標記可選符號(optional symbol)。下面這個詞法產生式,

是下面這個詞法產生式的縮寫形式:

它定義了一個區塊,用大括號標記 {...} 包裹起一個可選的 statement-list。
像這種每行一個進行列舉選項的形式,也可以通過使用 one of 將這些擴展列表寫進一行里。也就是說這是一種在一行中顯示這些選項的縮寫形式。比方說下面這個詞法產生式,

它的縮寫形式如下:

關于詞法文法(lexical grammar)的內容請參見第二章第三節、第四節和第五節。詞法文法的終結符號(terminal symbols)使用 Unicode 字符集,并具體詳述了字符是如何相互組合(combined)以構成標記(token,第二章第四節)、空白(white space,第二章第3.3節)以及預處理指令(pre-processing directives,第二章第五節)的。
每個 C# 程序的源文件都必須遵循詞法文法的 input 產生式(見第二章第三節)。
句法文法(syntactic grammar)在本章以及之后的附錄部分進行介紹。句法文法的終結符號(terminal symbols)由詞法文法定義為標記,而句法文法則指定了這些標記是如何相互組合并構成 C# 程序的。
每一個 C# 程序的源文件都必須遵循句法文法 compilation-unit 產生式(見第九章第一節)。
input 產生式定義了 C# 源文件的詞法結構。每個源文件都必須遵循這個詞法文法產生式(lexical grammar production)。

C# 源文件的詞法結構由行終結符(Line terminators,第二章第3.1節)、空白(white space,第二章第3.3節)、注釋(comments,第二章第3.2節)、標記(tokens,第二章第四節)以及預處理指令(pre-processing directives,第二章第五節)這五種基礎元素(basic elements)組成。對于這些基礎元素而言,只有標記(tokens)才是對句法文法有意義的(關于這一點,詳見第二章第2.3節)。
C# 源文件的詞法處理包括簡化文件為標記序列以便能輸入并進行句法分析。行終結符、空白和注釋用于分割每一個標記,而預處理指令能導致跳過源文件的某些區段,然而這些詞法元素(lexical elements)并不會影響到 C# 程序的句法結構。
當多個詞法文法產生式匹配到同一個源文件字符序列,詞法處理會盡力構成最長的詞法元素。字符序列 // 被處理為單行注釋的開頭,因為其詞法元素比單個斜杠 / 標記要長。
行終結符(line terminators)將 C# 源文件的字符分割為多行。

為了與增加有 EOF 標記(end-of-file markers)的源代碼編輯工具兼容,以及確保能以正確的行終結序列查看源代碼,下列轉換(transformations)將按順序應用于 C# 程序的每一個源文件:
Control-Z(U+001A),此字符將被刪除;carriage-return character(U+000D)、換行符 line feed(U+000A)、行分隔符 line separator(U+2028)或段落分隔符 paragraph separator(U+2029)的話,回車符 carriage-return character(U+000D)將被添加到源文件的最后位置。支持兩種形式的注釋:單行注釋(single-line comments)和分割注釋(delimited comments)。單行注釋以字符 // 起始、延續并終于該行之尾。分割注釋始于字符 /* 并止于字符 */,分割注釋支持跨行。

注釋不可嵌套(nest)。字符序列 /* 與 */ 置于 // 內部亦或是字符序列 // 和 /* 置于分割注釋內部均毫無意義。置于字符與字符串內部的注釋不會被處理。在例子
/* Hello, world program This program writes “hello, world” to the console*/class Hello{ static void Main() { System.Console.WriteLine("hello, world"); }}中,包含一個跨行注釋。在例子
// 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"); }}中則展示了多個單行注釋。
空白(white space)的定義包含了所有 Unicode Zs 集字符[2](包括空白字符 space character)、水平制表符(horizontal tab character)、垂直制表符(vertical tab character)和換頁符(form feed character)。

有以下幾種標記(tokens):標識符(identifiers)、關鍵字(keyWords)、文本(literals)、操作符(Operators)和標點符號(punctuators)。空白(white space)與注釋(comments)并非標記,它們只是標記的分隔符。

Unicode 字符轉義序列(Unicode character escape sequence)表示 Unicode 字符。Unicode 字符轉義序列處理于標識符(第二章第4.2節)、字符文本(character literals,第二章第4.4.4節)以及正則字符串文本(regular string literals,第二章第4.4.5節)內。除此以外,Unicode 字符轉義不會在其他任何地方被處理(比如在構成操作符、標點符或關鍵字時)。

Unicode 轉義序列用以 /u 或 /U 開頭、續接一個十六進制數的字符形式來表示單個 Unicode 字符。因 C# 字符與字符串使用 16 位(16-bit)編碼 Unicode 字符點,故區間在 U+10000 與 U+10FFFF 之間的 Unicode 字符不能在 C# 字符中使用;在字符串中則使用一個代理對(surrogate pair)來表示。不支持代碼點在 0x10FFFF 以上的 Unicode 字符。
Unicode 字符序列不允許多次轉換,比如字符串文本 /u005Cu005C 等于 /u005C 而不是 /(Unicode 值 /u005C 的字符是 /)。
class Class1{ static void Test(bool /u0066) { char c = '/u0066'; if (/u0066) System.Console.WriteLine(c.ToString()); }}在上面例子中我們多次使用了 /u0066,它是字母 f 的轉義字符序列,所以整個程序等價于:
class Class1{ static void Test(bool f) { char c = 'f'; if (f) System.Console.WriteLine(c.ToString()); }}區段(section)內的標識符規則與 Unicode 規范附錄 31 所推薦的一致,除了以下情況:
_ 允許用作初始字符(initial character,C 語言的一貫做法);@ 符號可以用于關鍵字的前綴以便使其可為標識符。
上面所提及的 Unicode 字符集(Unicode character classes)僅供參考,具體請參見 Unicode 規范(版本 3.0,第 4.5 節)。
有效的標識符包括 identifier1、_identifier2 和 @if。
在一個合格的程序中的標識符耶必須符合 Unicode Normalization Form C 的規范(定義于 Unicode 規范附錄 15)。當遇到一個不符合上述規范的標識符時,(如何處理)可由實現自行具體定義(implementation-defined),但不強制要求診斷(diagnostic)。
添加有前綴 @ 的關鍵字(keywords)可以成為一個標識符(identifiers),此舉在與其他編程語言配合時尤為有用。字符 @ 并非標識符的實際組成部分,故其它語言可將其(標識符)視為一個不帶前綴的普通標識符。帶有前綴 @ 的標識符被稱為逐字標識符(verbatim identifier)。允許將 @ 用作非關鍵字的標識符之
新聞熱點
疑難解答