diff libinterp/parse-tree/lex.ll @ 20623:e34692daf663

Extend parser to accept '_' in numbers. * NEWS: Announce change. * lex.ll: Define NUMBER to be a NUMREAL (real number) or NUMHEX (hex number). Define NUMREAL to begin with a digit (D) followed by more digits or an '_'. Define NUMHEX to begin with 0[xX], a hex digit (a-fA-F0-9), followed by '_' or more hex digits. Define EXPON to have a digit (D) followed by more digits or an '_'. * lex.ll (octave_base_lexer::handle_number): Strip out any underscores before processing number with sscanf. * parser.tst: Add tests for new behavior.
author Rik <rik@octave.org>
date Mon, 05 Oct 2015 14:05:58 -0700
parents 52ce821a52fd
children 7c0e10f035bd
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.ll	Fri Oct 09 16:52:49 2015 -0400
+++ b/libinterp/parse-tree/lex.ll	Mon Oct 05 14:05:58 2015 -0700
@@ -320,14 +320,17 @@
 %}
 
 D       [0-9]
+D_      [0-9_]
 S       [ \t]
 NL      ((\n)|(\r)|(\r\n))
 Im      [iIjJ]
 CCHAR   [#%]
 IDENT   ([_$a-zA-Z][_$a-zA-Z0-9]*)
 FQIDENT ({IDENT}(\.{IDENT})*)
-EXPON   ([DdEe][+-]?{D}+)
-NUMBER  (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+))
+EXPON   ([DdEe][+-]?{D}{D_}*)
+NUMREAL (({D}{D_}*\.?{D_}*{EXPON}?)|(\.{D}{D_}*{EXPON}?))
+NUMHEX  (0[xX][0-9a-fA-F][0-9a-fA-F_]*)
+NUMBER  ({NUMREAL}|{NUMHEX})
 
 ANY_EXCEPT_NL [^\r\n]
 ANY_INCLUDING_NL (.|{NL})
@@ -1124,9 +1127,9 @@
 // the constant.
 %}
 
-{D}+/\.[\*/\\^\'] |
+{D}{D_}*/\.[\*/\\^\'] |
 {NUMBER} {
-    curr_lexer->lexer_debug ("{D}+/\\.[\\*/\\\\^\\']|{NUMBER}");
+    curr_lexer->lexer_debug ("{D}{D_}*/\\.[\\*/\\\\^\\']|{NUMBER}");
 
     if (curr_lexer->previous_token_may_be_command ()
         &&  curr_lexer->space_follows_previous_token ())
@@ -2668,28 +2671,37 @@
 
   char *yytxt = flex_yytext ();
 
-  if (looks_like_hex (yytxt, strlen (yytxt)))
+  // Strip any underscores
+  char *tmptxt = strsave (yytxt);
+  char *rptr = tmptxt;
+  char *wptr = tmptxt;
+  while (*rptr)
+  {
+    *wptr = *rptr++;
+     wptr += (*wptr != '_');
+  }
+  *wptr = '\0';
+
+  if (looks_like_hex (tmptxt, strlen (tmptxt)))
     {
       unsigned long ival;
 
-      nread = sscanf (yytxt, "%lx", &ival);
+      nread = sscanf (tmptxt, "%lx", &ival);
 
       value = static_cast<double> (ival);
     }
   else
     {
-      char *tmp = strsave (yytxt);
-
-      char *idx = strpbrk (tmp, "Dd");
+      char *idx = strpbrk (tmptxt, "Dd");
 
       if (idx)
         *idx = 'e';
 
-      nread = sscanf (tmp, "%lf", &value);
-
-      delete [] tmp;
+      nread = sscanf (tmptxt, "%lf", &value);
     }
 
+  delete [] tmptxt;
+
   // If yytext doesn't contain a valid number, we are in deep doo doo.
 
   assert (nread == 1);