@@ -124,7 +124,7 @@ static void addlit(char *ytext, int yleng, core_yyscan_t yyscanner);
124124static void addlitchar (unsigned char ychar, core_yyscan_t yyscanner);
125125static char *litbufdup (core_yyscan_t yyscanner);
126126static 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 );
128128static void addunicode (pg_wchar c, yyscan_t yyscanner);
129129
130130#define yyerror (msg ) scanner_yyerror(msg, yyscanner)
@@ -385,25 +385,40 @@ operator {op_chars}+
385385 * Unary minus is not part of a number here. Instead we pass it separately to
386386 * the parser, and there it gets coerced via doNegate().
387387 *
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.
389389 *
390390 * {realfail} is added to prevent the need for scanner
391391 * backup when the {real} rule fails to match completely.
392392 */
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 }
403418real_junk {real }{ident_start }
404419
405- param \$ {integer }
406- param_junk \$ {integer }{ident_start }
420+ param \$ {decinteger }
421+ param_junk \$ {decinteger }{ident_start }
407422
408423other .
409424
@@ -983,20 +998,44 @@ other .
983998 yyerror (" trailing junk after parameter" );
984999 }
9851000
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 } {
9871022 SET_YYLLOC ();
988- return process_integer_literal (yytext, yylval );
1023+ yyerror ( " invalid octal integer " );
9891024 }
990- {decimal } {
1025+ {binfail } {
1026+ SET_YYLLOC ();
1027+ yyerror (" invalid binary integer" );
1028+ }
1029+ {numeric } {
9911030 SET_YYLLOC ();
9921031 yylval->str = pstrdup (yytext);
9931032 return FCONST;
9941033 }
995- {decimalfail } {
1034+ {numericfail } {
9961035 /* throw back the .., and treat as integer */
9971036 yyless (yyleng - 2 );
9981037 SET_YYLLOC ();
999- return process_integer_literal (yytext, yylval);
1038+ return process_integer_literal (yytext, yylval, 10 );
10001039 }
10011040{real } {
10021041 SET_YYLLOC ();
@@ -1007,11 +1046,23 @@ other .
10071046 SET_YYLLOC ();
10081047 yyerror (" trailing junk after numeric literal" );
10091048 }
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 } {
10111062 SET_YYLLOC ();
10121063 yyerror (" trailing junk after numeric literal" );
10131064 }
1014- {decimal_junk } {
1065+ {numeric_junk } {
10151066 SET_YYLLOC ();
10161067 yyerror (" trailing junk after numeric literal" );
10171068 }
@@ -1307,17 +1358,17 @@ litbufdup(core_yyscan_t yyscanner)
13071358}
13081359
13091360/*
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.
13121363 */
13131364static int
1314- process_integer_literal (const char *token, YYSTYPE *lval)
1365+ process_integer_literal (const char *token, YYSTYPE *lval, int base )
13151366{
13161367 int val;
13171368 char *endptr;
13181369
13191370 errno = 0 ;
1320- val = strtoint (token, &endptr, 10 );
1371+ val = strtoint (base == 10 ? token : token + 2 , &endptr, base );
13211372 if (*endptr != ' \0 ' || errno == ERANGE)
13221373 {
13231374 /* integer too large (or contains decimal pt), treat it as a float */
0 commit comments