summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-23 18:54:42 +0000
committerPaul Phillips <paulp@improving.org>2009-10-23 18:54:42 +0000
commit3803528e26e37fbd5b56c00339077ad29734f050 (patch)
tree65174ff86535d2262d298482286d3537dbe0d0ed /src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
parent3926c98936f79d25e1fcd2e0c206e3cb35f7ada8 (diff)
downloadscala-3803528e26e37fbd5b56c00339077ad29734f050.tar.gz
scala-3803528e26e37fbd5b56c00339077ad29734f050.tar.bz2
scala-3803528e26e37fbd5b56c00339077ad29734f050.zip
Reorg of number parsing to use more direct logic.
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/parser/Scanners.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala90
1 files changed, 49 insertions, 41 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 150de8db4d..acc2029eb6 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -731,6 +731,7 @@ trait Scanners {
/** Read a number into strVal and set base
*/
protected def getNumber() {
+ def isDigit(c: Char) = java.lang.Character isDigit c
val base1 = if (base < 10) 10 else base
// read 8,9's even if format is octal, produce a malformed number error afterwards.
while (digit2int(ch, base1) >= 0) {
@@ -738,52 +739,59 @@ trait Scanners {
nextChar()
}
token = INTLIT
- if (base <= 10 && ch == '.') {
- val lookahead = lookaheadReader
- lookahead.nextChar()
- def restOfNumber() = {
- putChar(ch)
- nextChar()
- getFraction()
- }
- lookahead.ch match {
- case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
- return restOfNumber()
-
- /** Backquoted idents like 22.`foo` */
- case '`' =>
- return setStrVal()
-
- /** These letters may be part of a literal, or a method invocation on an Int */
- case 'd' | 'D' | 'f' | 'F' =>
- lookahead.nextChar()
- if (!isIdentifierPart(lookahead.ch))
- return restOfNumber()
-
- /** A little more special handling for e.g. 5e7 */
- case 'e' | 'E' =>
- lookahead.nextChar()
- val ch = lookahead.ch
- if (!isIdentifierPart(ch) || (ch >= '0' && ch <= '9') || ch == '+' || ch == '-')
- return restOfNumber()
+ /** When we know for certain it's a number after using a touch of lookahead */
+ def restOfNumber() = {
+ putChar(ch)
+ nextChar()
+ getFraction()
+ }
+ def restOfUncertainToken() = {
+ def isEfd = ch match { case 'e' | 'E' | 'f' | 'F' | 'd' | 'D' => true ; case _ => false }
+ def isL = ch match { case 'l' | 'L' => true ; case _ => false }
- case _ =>
- if (!isIdentifierStart(lookahead.ch))
- return restOfNumber()
+ if (base <= 10 && isEfd)
+ getFraction()
+ else {
+ setStrVal()
+ if (isL) {
+ nextChar()
+ token = LONGLIT
+ }
+ else checkNoLetter()
}
}
- if (base <= 10 &&
- (ch == 'e' || ch == 'E' ||
- ch == 'f' || ch == 'F' ||
- ch == 'd' || ch == 'D')) {
- return getFraction()
+
+ if (base > 10 || ch != '.')
+ restOfUncertainToken()
+ else {
+ val lookahead = lookaheadReader
+ val isDefinitelyNumber =
+ (lookahead.getc(): @switch) match {
+ /** Another digit is a giveaway. */
+ case '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' =>
+ true
+
+ /** Backquoted idents like 22.`foo`. */
+ case '`' =>
+ return setStrVal() /** Note the early return **/
+
+ /** These letters may be part of a literal, or a method invocation on an Int */
+ case 'd' | 'D' | 'f' | 'F' =>
+ !isIdentifierPart(lookahead.getc())
+
+ /** A little more special handling for e.g. 5e7 */
+ case 'e' | 'E' =>
+ val ch = lookahead.getc()
+ !isIdentifierPart(ch) || (isDigit(ch) || ch == '+' || ch == '-')
+
+ case x =>
+ !isIdentifierStart(x)
+ }
+
+ if (isDefinitelyNumber) restOfNumber()
+ else restOfUncertainToken()
}
- setStrVal()
- if (ch == 'l' || ch == 'L') {
- nextChar()
- token = LONGLIT
- } else checkNoLetter()
}
/** Parse character literal if current character is followed by \',