您的位置:首页 > 编程语言 > Java开发

JAVA语言规范学习笔记(3)

2006-04-27 15:28 531 查看
开始学习JAVA的词汇结构了。JAVA程序是用unicode来表示的,比如我们常用到的换行符。所有的unicode都会强制转化为一系列的input elements,包括空格,注释,和tokens。JAVA的发展和unicode的发展是密不可分的。unicode的发展我们可以参考它的官方网站:http://www.unicode.org。JAVA编程语言是用UTF-16来描述文本的,只有少数的API类使用UTF-32,JAVA的平台提供了两者之间转化的方法。除了注释,标识符,字符常量,字符串常量,所有的input elements都是ASCII码组成。Lexical Translations词汇的翻译我们以后称之为Lexical Translations分为三步:1、原始的unicode stream所有的转义字符转化为对应的unicode字符。转义字符的形式是/uXXXX,其中XXXX代表的是十六进制的值。用ASCII码字符的程序在这个转化中也是适用的。2、利用第一步转化来的unicode字符,将其变为input elements和换行符。3、使用第二步转化来的input elements和换行符,去掉其中的空格、注释,就形成了我在JAVA语言规范学习笔记(2)中提到的tokens,然后利用这些tokens做语法分析。在Lexical Translations的实现里,首先就必须识别出转义字符,以后我就称它Unicode Escapes,它是用/u后面紧接着是XXXX的UTF-16的十六进制值表示的,将它转化为对应的UTF-16 unicode 字符。而描述那些辅助字符的时候,就需要两个转义符。使用我在JAVA语言规范学习笔记(2)学到的表示形式,那么这一步的转化就可以这样来表示:UnicodeInputCharacter:        UnicodeEscape        RawInputCharacterUnicodeEscape:        / UnicodeMarker HexDigit HexDigit HexDigit HexDigitUnicodeMarker:        u        UnicodeMarker uRawInputCharacter:        any Unicode characterHexDigit: one of        0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F在这里,/,u,XXXX,这些都是ASCII码字符。在这个处理过程中,它会考察“/”后面还有多少“/”。XXXX只能为偶数不可以为奇数。比如“//u2297-/2297”这种情况会怎样处理?它处理后会变成“//u2297-”。一个合法的转义字符“/”后面紧接着一个或多个“u”,但是最后一个“u”后面却没有“XXXX”,编译时就会报错。再看一个“/u005cu005a”,因为“005c”的值是“/”,那么它就变成“/u005a”,而转化后的后续字符串不会再来一次转义的转化了。JAVA语言中也详细描述了如何将一个用unicode character编写的程序转化为一个用ASCII码字符的程序,这样就方便使用ASCII码字符的工具来处理它。如果你的系统里没有相应的字符,那么实现里就会用“/uXXXX”这种形式来代替。其实,这个里面涉及到的还和一些JAVA的编译法则有关,我们不必去深究编译上到底如何实现,只是利用这些编译上的法则或者说方法来学习JAVA语言的技术细节。实现下一步通过line terminators来给程序的unicode character形式来分行。line terminators是由JAVA编译器或其他系统组件来处理的。在注释里用“//”的形式来表现的。LineTerminator:        the ASCII
LF
character, also known as "newline"        the ASCII
CR
character, also known as "return"
   
the ASCII
CR
character followed by the ASCII
LF
characterInputCharacter:        UnicodeInputCharacter but not
CR
or
LF
这就是我们开始将到的第二步所处理得到的结果。
经过第一步和第二步的处理,我们得到了input character和line terminators,开始第三步的处理了。要将它们变成input element,就是没有空格、注释,只有语法分析才能接受的terminal symbols,叫做tokens。这个过程是这样表示的。
在原始的输入流中,如果“x”是在“y”之前的,在这里我们称作,“x”是在“y”的左边;而“y”是在“x”的右边。因为在输入流中所有的换行符已经被替换为unicode characters了。
而在上面的定义里White Space包括:ASCII码的空格、水平制表符、换页符合换行符。
WhiteSpace:        the ASCII SP character, also known as "space"        the ASCII HT character, also known as "horizontal tab"        the ASCII FF character, also known as "form feed"        LineTerminator
再来看注释的定义:
Comment:        TraditionalComment        EndOfLineComment
TraditionalComment:        / * CommentTail
EndOfLineComment:        / / CharactersInLineopt 
CommentTail:        * CommentTailStar        N4000otStar CommentTail
CommentTailStar:        /        * CommentTailStar        NotStarNotSlash CommentTail
NotStar:        InputCharacter but not *        LineTerminator
NotStarNotSlash:        InputCharacter but not * or /        LineTerminator
CharactersInLine:        InputCharacter        CharactersInLine InputCharacter
还要注意一点,注释是不会内嵌的。
 
标识符,必须由Java Letters和Java Digit组成,不限长度,但开头的必须是Java Letters,它不能是关键字、boolean常量、null常量。定义如下:
Identifier:        IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
IdentifierChars:        JavaLetter        IdentifierChars JavaLetterOrDigit
JavaLetter:        any Unicode character that is a Java letter 
JavaLetterOrDigit:        any Unicode character that is a Java letter-or-digit
只要是unicode characters中的字符都可以,甚至如中文、韩文、日文都可以用来做标识符。不信?你可以在你的系统上试试。你可以用Character.isJavaIdentifierStart(int)方法来判断这个字符是否为Java Letters,用Character.isJavaIdentifierPart(int)来判断这个字符是否为Java Letters和Java Digits。如果是,就返回true,否则返回false。Java Letters包括ASCII码中的拉丁字母A-Z和a-z,由于历史上的原因,下划线_和$也是。Java Digits则是ASCII码中的数字0-9。两个标识符相等时,那么它们中的字母和数字所对应的unicode也必须相等。
关键字,这个不必多讲。中间有两个需要提及,const和goto这两个是JAVA中的保留字。
常量的定义:
Literal:        IntegerLiteral        FloatingPointLiteral        BooleanLiteral        CharacterLiteral        StringLiteral        NullLiteral
首先来看IntegerLiteral,可以用十进制、十六进制、八进制三种形式
IntegerLiteral:        DecimalIntegerLiteral        HexIntegerLiteral              OctalIntegerLiteralDecimalIntegerLiteral:        DecimalNumeral IntegerTypeSuffixoptHexIntegerLiteral:        HexNumeral IntegerTypeSuffixoptOctalIntegerLiteral:           OctalNumeral IntegerTypeSuffixoptIntegerTypeSuffix: one of        l L
Long型的常量后面要加上ASCII码字符的l或L来表示,建议用L,以免和1混淆。
十进制的常量是用ASCII码字符的0~9来表示的,其语法定义如下:
DecimalNumeral:        0        NonZeroDigit DigitsoptDigits:        Digit        Digits DigitDigit:        0        NonZeroDigitNonZeroDigit: one of        1 2 3 4 5 6 7 8 9
十六进制则是用0x或者0X作为前缀,后面是ASCII码字符中数字的0~9和字母的A~Z或a~z来表示,定义如下:
HexNumeral:        0 x HexDigits        0 X HexDigitsHexDigits:        HexDigit        HexDigit HexDigitsHexDigit: one of        0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
八进制的表示是用0作为前缀,后面是ASCII码字符中数字的0~7来表示,定义如下:
OctalNumeral:        0 OctalDigitsOctalDigits:        OctalDigit        OctalDigit OctalDigitsOctalDigit: one of        0 1 2 3 4 5 6 7
每一种整形的常量都有其表示数的范围,如果你使用整型常量赋值时,如果超出了它的范围,那么在编译时就会报错。
浮点型常量是由一个整型部分、一个小数点、一个小数部分、一个指数部分和一个类型的后缀表示的。如果是用十进制的形式来表示,如果有指数部分,那么是在数字后面用一个“e”或者“E”加上一个带符号的数字来表示。而用十六进制表是时,如果有指数部分,那么是在数字后面用一个“p”或者“P”加上一个带符号的数字来表示。
如果浮点类型是float时,那么后缀为ASCII码字符f或F;如果浮点类型是double时,那么后缀为ASCII码字符d或D。定义如下:
FloatingPointLiteral:        DecimalFloatingPointLiteral        HexadecimalFloatingPointLiteralDecimalFloatingPointLiteral:        Digits . Digitsopt ExponentPartopt FloatTypeSuffixopt      . Digits ExponentPartopt FloatTypeSuffixopt      Digits ExponentPart FloatTypeSuffixopt        Digits ExponentPartopt FloatTypeSuffixExponentPart:        ExponentIndicator SignedIntegerExponentIndicator: one of        e ESignedInteger:        Signopt DigitsSign: one of        + -FloatTypeSuffix: one of        f F d DHexadecimalFloatingPointLiteral:        HexSignificand BinaryExponent FloatTypeSuffixoptHexSignificand:        HexNumeral        HexNumeral .        0x HexDigitsopt . HexDigits        0X HexDigitsopt . HexDigitsBinaryExponent:        BinaryExponentIndicator SignedIntegerBinaryExponentIndicator:one of        p P
无论是float或double类型,它们分别用IEEE 754标准中的32-bit和64-bit二进制格式来表示的。从unicode字符串转化为浮点类型时,使用的是Float和Double这两个类的valueOf()方法,这两个类在java.lang.*这个package里。
同样,浮点类型也是有范围的,如果你使用时超出了它们的范围时,编译器也会报错的。那么如果你想在你的程序里表示无限大,但又不想让编译器报错,那可以使用Float和Double这两个类的POSITIVE_INFINITYNEGATIVE_INFINITY这两个常量来表示。Float和Double这两个类还有一个预定义的常量NaN,它表示这不是一个数字。
 
Boolean Literals
boolean类型只有两个常量形式,true和false。定义如下:
BooleanLiteral: one of        true false
 
Character Literals
字符常量可以用来表示字符或者转义字符,用一对单引号表示‘’。定义形式如下:
CharacterLiteral:        ' SingleCharacter '        ' EscapeSequence 'SingleCharacter:        InputCharacter but not ' or /
如果字符常量SingleCharacter和EscapeSequence不是以’结尾,那么编译时就会报错;如果行终结符出现在字符常量中的‘之后和’之前,那么编译时就会报错。
 
String Literals
字符串常量则是由一个或多个字符组成,用“”来表示。其定义如下:
StringLiteral:        " StringCharactersopt "StringCharacters:        StringCharacter        StringCharacters StringCharacterStringCharacter:        InputCharacter but not " or /        EscapeSequence
由于unicode的转义在第一步中就完成了,所以在字符串中出现:“/u000a”在第一步中就完成和换行符第二步中也完成了的,是不正确的。但是我们可以用另外的一种形式来代替,比如换行“/n”,回车“/r”。字符串是不变的。
 
Escape Sequences for Character and String Literals
下面定义的是一些可以在字符常量和字符串常量中使用的转义字符:
EscapeSequence:        / b                     /* /u0008: backspace BS                   */        / t                     /* /u0009: horizontal tab HT              */        / n                     /* /u000a: linefeed LF                    */        / f                     /* /u000c: form feed FF           */        / r                     /* /u000d: carriage return CR             */        / "                     /* /u0022: double quote "             */        / '                     /* /u0027: single quote '          */        / /                     /* /u005c: backslash /                     */        OctalEscape               /* /u0000 to /u00ff: from octal value   */OctalEscape:        / OctalDigit        / OctalDigit OctalDigit        / ZeroToThree OctalDigit OctalDigitOctalDigit: one of        0 1 2 3 4 5 6 7ZeroToThree: one of        0 1 2 3
如果在使用时不是按上述的形式来写,编译时就会报错。
 
The Null Literal
这个定义很简单:
NullLiteral:        null
 
Separators
分隔符的定义:
Separator: one of        (       )       {       }       [       ]       ;       ,       .
 
Operators
37个运算符的定义:
Operator: one of        =       >    <    !       ~       ?       :        ==      <=   >=   !=      &&      ||      ++      --        +       -       *       /       &   |       ^       %       <<        >>        >>>        +=      -=      *=      /=      &=  |=      ^=      %=      <<=       >>=       >>>=
 
至此,JAVA中的词汇结构就到这里给出了一个全貌。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息