[Rd] Feature Request: Allow Underscore Separated Numbers

Ivan Krylov kry|ov@r00t @end|ng |rom gm@||@com
Sun Jul 17 08:57:22 CEST 2022


On Sat, 16 Jul 2022 11:17:17 -0400
Duncan Murdoch <murdoch.duncan using gmail.com> wrote:

> I think there's an issue with hex values.  For example:
> 
>  > 0xa_2  
> [1] 162
>  > 0x2_a  
> Error: unexpected input in "0x2_"

You're right, thanks! Should have checked for hex-digits when in
hex-literal mode.

One last try because I don't want to leave a bug I had introduced
myself, but as you say in your other message, this is both incomplete
without tests and documentation and effectively dead unless an R Core
member picks the whole proposal up:

--- src/main/gram.y	(revision 82598)
+++ src/main/gram.y	(working copy)
@@ -2091,7 +2091,9 @@
     int k, c;
 
     c = xxgetc();
-    if (isdigit(c)) k = 1; else k = 2;
+    if (isdigit(c)) k = 1;
+    else if (('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')) k = 2;
+    else k = 3;
     xxungetc(c);
     return k;
 }
@@ -2526,7 +2528,7 @@
     YYTEXT_PUSH(c, yyp);
     /* We don't care about other than ASCII digits */
     while (isdigit(c = xxgetc()) || c == '.' || c == 'e' || c == 'E'
-	   || c == 'x' || c == 'X' || c == 'L')
+	   || c == 'x' || c == 'X' || c == 'L' || c == '_')
     {
 	count++;
 	if (c == 'L') /* must be at the end.  Won't allow 1Le3 (at present). */
@@ -2538,11 +2540,16 @@
 	    if (count > 2 || last != '0') break;  /* 0x must be first */
 	    YYTEXT_PUSH(c, yyp);
 	    while(isdigit(c = xxgetc()) || ('a' <= c && c <= 'f') ||
-		  ('A' <= c && c <= 'F') || c == '.') {
+		  ('A' <= c && c <= 'F') || c == '.' || c == '_') {
 		if (c == '.') {
 		    if (seendot) return ERROR;
 		    seendot = 1;
 		}
+		if (c == '_') {
+		    /* disallow underscores following 0x or followed by non-hexdigit */
+		    if (nd == 0 || typeofnext() >= 3) break;
+		    continue;
+		}
 		YYTEXT_PUSH(c, yyp);
 		nd++;
 	    }
@@ -2588,6 +2595,11 @@
 		break;
 	    seendot = 1;
 	}
+	/* underscores in significand followed by a digit must be skipped */
+	if (c == '_') {
+	    if (seenexp || typeofnext() >= 2) break;
+	    continue;
+	}
 	YYTEXT_PUSH(c, yyp);
 	last = c;
     }

I won't be sending any more unsolicited patches for this proposal.

-- 
Best regards,
Ivan



More information about the R-devel mailing list