@@ -124,7 +124,7 @@ static void addlit(char *ytext, int yleng, core_yyscan_t yyscanner);
124
124
static void addlitchar (unsigned char ychar, core_yyscan_t yyscanner);
125
125
static char *litbufdup (core_yyscan_t yyscanner);
126
126
static unsigned char unescape_single_char (unsigned char c, core_yyscan_t yyscanner);
127
- static int process_integer_literal (const char *token, YYSTYPE *lval);
127
+ static int process_integer_literal (const char *token, YYSTYPE *lval, int base );
128
128
static void addunicode (pg_wchar c, yyscan_t yyscanner);
129
129
130
130
#define yyerror (msg ) scanner_yyerror(msg, yyscanner)
@@ -385,25 +385,40 @@ operator {op_chars}+
385
385
* Unary minus is not part of a number here. Instead we pass it separately to
386
386
* the parser, and there it gets coerced via doNegate().
387
387
*
388
- * {decimalfail } is used because we would like "1..10" to lex as 1, dot_dot, 10.
388
+ * {numericfail } is used because we would like "1..10" to lex as 1, dot_dot, 10.
389
389
*
390
390
* {realfail} is added to prevent the need for scanner
391
391
* backup when the {real} rule fails to match completely.
392
392
*/
393
- digit [0 -9 ]
394
-
395
- integer {digit }+
396
- decimal (({digit }* \. {digit }+ )| ({digit }+ \. {digit }* ))
397
- decimalfail {digit }+ \.\.
398
- real ({integer }| {decimal })[Ee ][-+ ]? {digit }+
399
- realfail ({integer }| {decimal })[Ee ][-+ ]
400
-
401
- integer_junk {integer }{ident_start }
402
- decimal_junk {decimal }{ident_start }
393
+ decdigit [0 -9 ]
394
+ hexdigit [0 -9A -Fa -f ]
395
+ octdigit [0 -7 ]
396
+ bindigit [0 -1 ]
397
+
398
+ decinteger {decdigit }+
399
+ hexinteger 0[xX ]{hexdigit }+
400
+ octinteger 0[oO ]{octdigit }+
401
+ bininteger 0[bB ]{bindigit }+
402
+
403
+ hexfail 0[xX ]
404
+ octfail 0[oO ]
405
+ binfail 0[bB ]
406
+
407
+ numeric (({decinteger }\. {decinteger }? )| (\. {decinteger }))
408
+ numericfail {decdigit }+ \.\.
409
+
410
+ real ({decinteger }| {numeric })[Ee ][-+ ]? {decdigit }+
411
+ realfail ({decinteger }| {numeric })[Ee ][-+ ]
412
+
413
+ decinteger_junk {decinteger }{ident_start }
414
+ hexinteger_junk {hexinteger }{ident_start }
415
+ octinteger_junk {octinteger }{ident_start }
416
+ bininteger_junk {bininteger }{ident_start }
417
+ numeric_junk {numeric }{ident_start }
403
418
real_junk {real }{ident_start }
404
419
405
- param \$ {integer }
406
- param_junk \$ {integer }{ident_start }
420
+ param \$ {decinteger }
421
+ param_junk \$ {decinteger }{ident_start }
407
422
408
423
other .
409
424
@@ -983,20 +998,44 @@ other .
983
998
yyerror (" trailing junk after parameter" );
984
999
}
985
1000
986
- {integer } {
1001
+ {decinteger } {
1002
+ SET_YYLLOC ();
1003
+ return process_integer_literal (yytext, yylval, 10 );
1004
+ }
1005
+ {hexinteger } {
1006
+ SET_YYLLOC ();
1007
+ return process_integer_literal (yytext, yylval, 16 );
1008
+ }
1009
+ {octinteger } {
1010
+ SET_YYLLOC ();
1011
+ return process_integer_literal (yytext, yylval, 8 );
1012
+ }
1013
+ {bininteger } {
1014
+ SET_YYLLOC ();
1015
+ return process_integer_literal (yytext, yylval, 2 );
1016
+ }
1017
+ {hexfail } {
1018
+ SET_YYLLOC ();
1019
+ yyerror (" invalid hexadecimal integer" );
1020
+ }
1021
+ {octfail } {
987
1022
SET_YYLLOC ();
988
- return process_integer_literal (yytext, yylval );
1023
+ yyerror ( " invalid octal integer " );
989
1024
}
990
- {decimal } {
1025
+ {binfail } {
1026
+ SET_YYLLOC ();
1027
+ yyerror (" invalid binary integer" );
1028
+ }
1029
+ {numeric } {
991
1030
SET_YYLLOC ();
992
1031
yylval->str = pstrdup (yytext);
993
1032
return FCONST;
994
1033
}
995
- {decimalfail } {
1034
+ {numericfail } {
996
1035
/* throw back the .., and treat as integer */
997
1036
yyless (yyleng - 2 );
998
1037
SET_YYLLOC ();
999
- return process_integer_literal (yytext, yylval);
1038
+ return process_integer_literal (yytext, yylval, 10 );
1000
1039
}
1001
1040
{real } {
1002
1041
SET_YYLLOC ();
@@ -1007,11 +1046,23 @@ other .
1007
1046
SET_YYLLOC ();
1008
1047
yyerror (" trailing junk after numeric literal" );
1009
1048
}
1010
- {integer_junk } {
1049
+ {decinteger_junk } {
1050
+ SET_YYLLOC ();
1051
+ yyerror (" trailing junk after numeric literal" );
1052
+ }
1053
+ {hexinteger_junk } {
1054
+ SET_YYLLOC ();
1055
+ yyerror (" trailing junk after numeric literal" );
1056
+ }
1057
+ {octinteger_junk } {
1058
+ SET_YYLLOC ();
1059
+ yyerror (" trailing junk after numeric literal" );
1060
+ }
1061
+ {bininteger_junk } {
1011
1062
SET_YYLLOC ();
1012
1063
yyerror (" trailing junk after numeric literal" );
1013
1064
}
1014
- {decimal_junk } {
1065
+ {numeric_junk } {
1015
1066
SET_YYLLOC ();
1016
1067
yyerror (" trailing junk after numeric literal" );
1017
1068
}
@@ -1307,17 +1358,17 @@ litbufdup(core_yyscan_t yyscanner)
1307
1358
}
1308
1359
1309
1360
/*
1310
- * Process {integer} . Note this will also do the right thing with {decimal},
1311
- * ie digits and a decimal point.
1361
+ * Process {decinteger}, {hexinteger}, etc . Note this will also do the right
1362
+ * thing with {numeric}, ie digits and a decimal point.
1312
1363
*/
1313
1364
static int
1314
- process_integer_literal (const char *token, YYSTYPE *lval)
1365
+ process_integer_literal (const char *token, YYSTYPE *lval, int base )
1315
1366
{
1316
1367
int val;
1317
1368
char *endptr;
1318
1369
1319
1370
errno = 0 ;
1320
- val = strtoint (token, &endptr, 10 );
1371
+ val = strtoint (base == 10 ? token : token + 2 , &endptr, base );
1321
1372
if (*endptr != ' \0 ' || errno == ERANGE)
1322
1373
{
1323
1374
/* integer too large (or contains decimal pt), treat it as a float */
0 commit comments