一、C#的語句分析:
語法分析階段把輸入字符流轉換爲標記流。
1.1 輸入
input:
input-elementsopt
input-elements:
input-element
input-elements input-element
input-element:
comment
white-space
token
1.2 輸入字符
input-character:
any Unicode character
1.3 行結束符
line-terminator:
The carriage return character (U+000D)
The line feed character (U+000A)
The carriage return character followed by a line feed character
The line separator character (U+2028)
The paragraph separator character (U+2029)
1.4 註釋
C#支持兩種形式的註釋:規則註釋和單行註釋。
規則註釋以/*開始,並且以*/結束。規則註釋可以佔用一行的一部分,單行或多行。
比如:
/* Hello, world program
This program writes “Hello, world” to the console
*/
class Hello
{
static void Main() {
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"
Console.WriteLine("Hello, world");
}
}
介紹了多個單行註釋。
comment:
regular-comment
one-line-comment
regular-comment:
/ * rest-of-r egular-comment
rest-of-r egular-comment:
* rest-of-r egular-comment-star
not-star rest-of-r egular-comment
rest-of-r egular-comment-star:
/
* rest-of-r egular-comment-star
not-star-or-slash rest-of-r egular-comment
not-star:
Any input-character except *
not-star-or-slash:
Any input-character except * and /
one-line-comment:
/ / one-line-comment-text line-terminator
one-line-comment-text:
input-character
one-line-comment-text input-character
比如:
// This is a comment
int i;
/* This is a
multiline comment */
int j;
1.5 空白
white-space:
new-line
The tab character (U+0009)
The vertical tab character (U+000B)
The form feed character (U+000C)
The "control-Z" or "substitute" character (U+001A)
All characters with Unicode class "Zs"
1.6 標記
C#有五種標記:標識符、關鍵字、數據符號、操作符和標點。因爲空白像是標記的分割符,所以被忽略了。
token:
identifi er
keyword
literal
operator-or-punctuator
-------思多雅[天行健]版權所有,首發太平洋論論壇,轉載請註明-------
二、C#的句法分析
句法分析階段就是把標記流轉換爲可執行代碼。
2.1 標識符
標識符的規則符合統一字符編碼標準3.0,除了下劃線允許使用起首大寫字母,格式化字符 (類Cf)不允許用於標識符而統一字符編碼標準中的escape 字符允許用在標識符中。
identifi er:
available-identifi er
@ identifie r-or-keyword
available-identifi er:
An identifi er-or-keyword that is not a keyword
identifi er-or-keyword:
identifi er-start-character identif ier-part-charactersopt
identifi er-start-character:
letter-character
underscore-character
identifi er-part-characters:
identifi er-part-character
identifi er-part-characters identifi er-part-character
identifi er-part-character:
letter-character
combining-character
decimal-digit-character
underscore-character
letter-character:
A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl
A unicode-character-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-character-escape-sequence representing a character of classes Mn or Mcdecimal-digit-
character:
A Unicode character of the class Nd
A unicode-character-escape-sequence representing a character of the class Nd
underscore-character:
A Unicode character of the class Pc
A unicode-character-escape-sequence representing a character of the class Pc
合法標識符的例子包括“identifier1”, “_identifier2”, 和 “@if”。
前綴“@”使得可以在標識符中使用關鍵詞。實際上字符@不是標識符的一部分,所以如果沒有這個前綴,可能在另外一種語言中被視爲通常的標識符。
注意:不是關鍵字也在標識符中使用前綴@是允許的,但是這是一種很不好的風格。
示例:
class @class
{
static void @static(bool @bool) {
if (@bool)
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
class Class1
{
static void M {
@class.@static(true);
}
}
定義了一個名爲“class”的類,有一個靜態方法名爲“static”,他使用了一個名爲“bool”的參數。
2.2 關鍵字
關鍵字是類似於標識符的保留字符序列,除非用@字符開頭,否則不能用作標識符。
關鍵字: one of
abstract 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 static string struct switch
this throw true try typeof
uint ulong unchecked unsafe ushort
using virtual void while
2.3 數據符號
數據符號是數值的源代碼表示。
literal:
boolean-literal
integer-literal
real-literal
character-literal
string-literal
null-literal
2.3.1 二進制數據符號
這裏有兩種二進制數值:true 和false。
boolean-literal:
true
false
2.3.2 整數數據符號
整數數據符號有兩種可能的形式:十進制和十六進制。
integer-literal:
decimal-integer-literal
hexadecimal-integer-literal
decimal-integer-literal:
decimal-digits integer-type-suff ixopt
decimal-digits:
decimal-digit
decimal-digits decimal-digit
decimal-digit: one of
0 1 2 3 4 5 6 7 8 9
integer-type -suff ix: one of
U u L l UL Ul uL ul LU Lu lU lu
hexadecimal-integer-literal:
0x hex-digits integer-type-suff ixopt
hex-digits:
hex-digit
hex-digits hex-digit
hex-digit: one of
0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
整數數據符號的類型按下面確定:
1 如果數據符號沒有後綴,它就有這些類型中的第一個,這些類型可以表示出它的數值:int、uint、
long、ulong 。
2 如果數據符號有後綴U 或u,它就有這些類型中的第一個,這些類型可以表示出它的數值:uint,
ulong。
3 如果數據符號有後綴L 或l,If the literal is suffixed by L or l, 它就有這些類型中的第一個,這些類型可以表示出它的數值:long, ulong。
4 如果數據符號有後綴UL、Ul、uL、ul、LU、Lu、lU或lu,它的類型就是ulong。
如果用整數數據符號表示的數值超出了ulong 類型,就會產生錯誤。
同時,爲了允許最小的可能的int 和long 數值可以用十進制整數描述,存在下面兩個規則:
1 當一個十進制整數數據符號的數值爲2147483648 (231),並且沒有整數類型後綴,而操作數有一元負操作符(§錯誤!未找到引用源。)時,結果是int 類型的常數,數值爲-2147483648 (-231)。在所有其它情況下,這樣的一個十進制整數數據符號是uint 類型。
2 當一個十進制整數數據符號的數值爲9223372036854775808 (263),並且沒有整數類型後綴或整數類型後綴L 或l,而操作數有一元負操作符(§錯誤!未找到引用源。)時,結果是long 類型的常數,數值爲-9223372036854775808 (-263)。在所有其它情況下,這樣的一個十進制整數數據符號是ulong 類型。
2.3.2.1 實數據符號
real-literal:
decimal-digits . decimal-digits exponen t-par topt real-type-suff ixopt
. decimal-digits exponent-partopt real-typ e-suff ixopt
decimal-digits exponent-part real-type-suff ixopt
decimal-digits real-type-suff ix
exponent-part:
e signopt decimal-digits
E signopt decimal-digits
sign: one of
+ -
real-type-suff ix: one of
F f D d M m
如果沒有指定real 類型後綴,實數據符號的類型是double。不然的話,實類型後綴決定了實數據符號,相應的規則如下:
1 一個實數據以F 或f 爲後綴是float 類型。例如數據符號1f、1.5f、1e10f、和-123.456F都是float類型數據。
2 一個實數據以D 或d 爲後綴是double 類型。例如數據符號1d、1.5d、1e10d、和-123.456d都是double 類型數據。
3 一個實數據以M 或m 爲後綴是decimal類型。例如數據符號1m、1.5m、1e10m、和-123.456m都是decimal類型數據。
這裏要重點注意一下,如果所指定的數據符號不能用指定類型表示,在編譯時會產生錯誤。
2.3.2.2 字符數據符號
字符數據符號是一個用號括起來的單個字符,如'a'。
character-literal:
' character '
character:
single-character
simple-escape-sequence
hexadecimal-escape-sequence
unicode-character-escape-sequence
single-character:
Any character except ' (U+0027), / (U+005C), and new-line
simple-escape-sequence: one of
/' /" // /0 /a /b /f /n /r /t /v
hexadecimal-escape-sequence:
/x hex-digit hex-digitopt hex-digitopt hex-digitopt
在一個單轉意符序列或一個十六進制轉意符序列中,一個跟在反斜槓字符(/)後面的字符必然是下面的字符之一: '、"、/、0、a、b、f、n、r、t、x、v,否則,在編譯是會發生錯誤。
一個簡單的轉意符序列表示了統一的字符編碼的字符編碼,如下表所示。
轉意序列 字符名稱 Unicode 編碼
/' Single quote 0x0027
/" Double quote 0x0022
// Backslash 0x005C
/0 Null 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
2.3.2.3 字符串數據符號
C# 支持兩種形式的字符串數據符號:規則字符串數據符號和逐字的字符串數據符號。規則字符串數字
符號由用雙引號括起0 或更多字符組成,例如"Hello, world",並且也許會包括簡單轉意序列(例如/t
表示tab 字符)和十六進制轉意序列。
逐字的字符串數據符號由一個@字符後面跟着雙引號括起的0 或者更多字符組成。一個簡單的例子是
@"Hello, world"。在一個逐字字符串數據符號中,分割符間的字符通常認爲是逐字的,只有引用轉意序列例
外。特別的是,簡單轉意序列和十六進制轉意序列在逐字字符串數據符號中不支持。一個逐字字符串數據符號可
能會跨越很多行。
string-literal:
regular-string-literal
verbatim-string-literal
regular-string-literal:
" regular-string-literal-charactersopt "
regular-string-literal-characters:
regular-string-literal-character
regular-string-literal-characters regular-string-literal-character
regular-string-literal-character:
single-regular-string-literal-character
simple-escape-sequence
hexadecimal-escape-sequence
unicode-character-escape-sequence
single-regular-string-literal-character:
Any character except " (U+0022), / (U+005C), and new-line
verbatim-string-literal:
@" verbatim -string-literal-charactersopt "
verbatim-string-literal-characters:
verbatim-string-literal-character
verbatim-string-literal-characters 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:
""
示例
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"
string f = @"Joe said ""Hello"" to me"; // Joe said "Hello"
string g = "////sever//share//file.txt"; // //server/share/file.txt
string h = @"//server/share/file.txt"; // //server/share/file.txt
string i = "one/ntwo/nthree";
string j = @"one
two
three";
介紹了多種字符串數據符號。最後一個字符串數據j 是逐字字符串數據,它橫跨了很多行。在引號間的字符,包括空白如轉行字符,都是逐字複製的。
2.3.2.4 null 數據字符
null-literal:
null
2.3.2.5操作符和標點
這裏有許多種操作符和標點。操作符用於表達式來描述操作涉及到一個或多個操作數。例如,表達式a
+b 使用+操作符來把a 和b 相加。標點用於組織和分割。例如標點;是用來分割在聲明列表中出現的聲明。
operator-or-punctuator: one of
{ } [ ] ( ) . , : ;
+ - * / % & | ^ ! ~
= < > ? ++ -- && || << >>
== != <= >= += -= *= /= %= &=
|= ^= <<= >>= ->
2.3.2..6 Unicode 字符轉意字符序列
一個Unicode 字符轉意字符序列代表了一個Unicode 字符。Unicode 字符轉意字符序列在標識符,字符串數據符號和字符數據符號中是被允許的。
unicode-character-escape-sequence:
/u hex-digit hex-digit hex-digit hex-digit
不能實現多重轉換。例如字符串數據“/u005Cu005C”與 “/u005C” rather than “//”是相等的。 (Unicode數值/u005C是字符 “/”。)
示例:
class Class1
{
static void Test(bool /u0066) {
char c = '/u0066';
if (/u0066)
Console.WriteLine(c.ToString());
}
}
介紹了許多/u0066 的使用,它是字母“f”的字符轉意序列。這個程序等價於
class Class1
{
static void Test(bool f) {
char c = 'f';
if (f)
Console.WriteLine(c.ToString());
}
}
C#的語句分析
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.