C#专题之C#的语法和句法分析

 作者:思多雅[天行健] 2008-10-05发布    
    正如前面的专题所说,编译从原理上来说包括了词法分析、语法分析、存储的组织与分配、中间语言、语法制导翻译、代码生成与优化这几大部分,下面我们来看看C#的语法分析和句法分析:

一、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()); 
            } 
       } 

-------思多雅[天行健]版权所有,首发太平洋论论坛,转载请注明-------
三、学习建议
学习这一章,有三个好的建议:
自己根据本专题后续的的一些实例自己体验一下;
到图书馆找些《编译原理》的书,多看一下;
实再不然,先知道有这么一回事,然后回过头再来学习这一部分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值