diff --git a/src/main/org/codehaus/groovy/antlr/groovy.g b/src/main/org/codehaus/groovy/antlr/groovy.g
index 31ffb4d..8e67c14 100644
--- a/src/main/org/codehaus/groovy/antlr/groovy.g
+++ b/src/main/org/codehaus/groovy/antlr/groovy.g
@@ -4122,6 +4122,22 @@ options {
     // TODO:  Recognize all the Java identifier parts here (except '$').
     ;
 
+protected
+DIGITS_WITH_UNDERSCORE
+options {
+    paraphrase="a sequence of digits and underscores, bordered by digits";
+}
+    :   DIGIT (DIGITS_WITH_UNDERSCORE_OPT)?
+    ;
+   
+protected
+DIGITS_WITH_UNDERSCORE_OPT
+options {
+    paraphrase="a sequence of digits and underscores with maybe underscore starting";
+}
+    :   (DIGIT | '_')* DIGIT
+    ;
+    
 // a numeric literal
 NUM_INT
 options {
@@ -4149,27 +4165,29 @@ options {
 *OBS*/
         // TODO:  This complex pattern seems wrong.  Verify or fix.
         (   '0' {isDecimal = true;} // special case for just '0'
-            (   ('x'|'X')
+            (   // hex digits
+                ('x'|'X')
+                {isDecimal = false;}
+                HEX_DIGIT 
+                (   options { warnWhenFollowAmbig=false; }
+                    : (options { warnWhenFollowAmbig=false; } : HEX_DIGIT | '_')*
+                    HEX_DIGIT
+                )?
+            
+            |   //binary literal
+                ('b'|'B') ('0'|'1') (('0'|'1'|'_')* ('0'|'1'))?
                 {isDecimal = false;}
-                (                                                                                   // hex
-                    // the 'e'|'E' and float suffix stuff look
-                    // like hex digits, hence the (...)+ doesn't
-                    // know when to stop: ambig. ANTLR resolves
-                    // it correctly by matching immediately. It
-                    // is therefor ok to hush warning.
-                    options {
-                        warnWhenFollowAmbig=false;
-                    }
-                :   HEX_DIGIT
-                )+
 
             |   //float or double with leading zero
-                (('0'..'9')+ ('.'('0'..'9')|EXPONENT|FLOAT_SUFFIX)) => ('0'..'9')+
+                (   DIGITS_WITH_UNDERSCORE
+                    ( '.' DIGITS_WITH_UNDERSCORE | EXPONENT | FLOAT_SUFFIX)
+                ) => DIGITS_WITH_UNDERSCORE
 
-            |   ('0'..'7')+                                                                     // octal
+            |   // octal
+                ('0'..'7') (('0'..'7'|'_')* ('0'..'7'))?                                                                    
                 {isDecimal = false;}
             )?
-        |   ('1'..'9') ('0'..'9')*  {isDecimal=true;}               // non-zero decimal
+        |   ('1'..'9') (DIGITS_WITH_UNDERSCORE_OPT)? {isDecimal=true;}               // non-zero decimal
         )
         (   ('l'|'L') { _ttype = NUM_LONG; }
         |   ('i'|'I') { _ttype = NUM_INT; }
@@ -4179,7 +4197,7 @@ options {
         |
             (~'.' | '.' ('0'..'9')) =>
             {isDecimal}?
-            (   '.' ('0'..'9')+ (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;} | g2:BIG_SUFFIX {t=g2;})?
+            (   '.' DIGITS_WITH_UNDERSCORE (e:EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;} | g2:BIG_SUFFIX {t=g2;})?
             |   EXPONENT (f3:FLOAT_SUFFIX {t=f3;} | g3:BIG_SUFFIX {t=g3;})?
             |   f4:FLOAT_SUFFIX {t=f4;}
             )
@@ -4211,7 +4229,7 @@ EXPONENT
 options {
     paraphrase="an exponent";
 }
-    :   ('e'|'E') ('+'|'-')? ('0'..'9')+
+    :   ('e'|'E') ('+'|'-')? ('0'..'9'|'_')* ('0'..'9')
     ;
 
 
diff --git a/src/main/org/codehaus/groovy/syntax/Numbers.java b/src/main/org/codehaus/groovy/syntax/Numbers.java
index 9b61d61..636e777 100644
--- a/src/main/org/codehaus/groovy/syntax/Numbers.java
+++ b/src/main/org/codehaus/groovy/syntax/Numbers.java
@@ -140,6 +140,9 @@ public class Numbers
 
     public static Number parseInteger( String text )
     {
+        // remove place holder underscore before starting
+        text = text.replace("_", "");
+        
         char c = ' ';
         int length = text.length();
 
@@ -160,16 +163,17 @@ public class Numbers
         // Determine radix (default is 10).
 
         int radix = 10;
-        if( text.charAt(0) == '0' && length > 1 )
-        {
-            if( (c = text.charAt(1)) == 'X' || c == 'x' )
-            {
+        if( text.charAt(0) == '0' && length > 1 ) {
+            c = text.charAt(1);
+            if( c == 'X' || c == 'x' ) {
                 radix = 16;
                 text = text.substring( 2, length);
                 length -= 2;
-            }
-            else
-            {
+            } else if ( c == 'B' || c == 'b' ) { 
+                radix = 2;
+                text = text.substring(2, length);
+                length -= 2;
+            } else {
                 radix = 8;
             }
         }
@@ -249,6 +253,7 @@ public class Numbers
 
     public static Number parseDecimal( String text )
     {
+        text = text.replace("_", "");
         int length = text.length();
 
 
