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
LFcharacter, also known as "newline" the ASCII
CRcharacter, also known as "return"
the ASCII
CRcharacter followed by the ASCII
LFcharacterInputCharacter: UnicodeInputCharacter but not
CRor
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_INFINITY和NEGATIVE_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中的词汇结构就到这里给出了一个全貌。
相关文章推荐
- JAVA语言规范学习笔记(4)
- JAVA语言规范学习笔记(1)
- JAVA语言规范学习笔记(2)
- Java学习笔记之语言基础――取模运算的正负符号
- Java面对对象编程---学习笔记(JAVA语言基础)
- java学习笔记]java语言基础概述之内存的划分&堆和栈
- java语言学习笔记
- java学习笔记,1,java语言基础知识
- JAVA与模式 学习笔记(一) 统一的建模语言UML介绍(1)
- Java语言基础学习笔记——基础语法
- [java学习笔记]java语言基础概述之函数的定义和使用&函数传值问题
- Java学习笔记四。设计模式、基本数据类型、包装类、异常、断言、包、访问权限、命名规范、jar
- 关于java语言中容器的学习笔记
- Java语言基础_学习笔记_强制类型转换
- JVM学习笔记之-JAVA语言概述.
- Java2核心技术第七版的学习笔记(三) Fundamental Programming Structures in Java(Java语言的基础)(二)
- OCJP(310-065)精选笔记之-Java语言编码规范(Code Conventions)
- Java学习笔记之语言基础―― Java中浮点数除0问题
- Java基础学习(02Java语言的特点、机制与规范)
- Java语言基础学习笔记(五)