@@ -844,11 +844,17 @@ public function parseNumber()
844844 //
845845 // 10 -------------------[ 0 to 9 ]-------------------> 4
846846 //
847+ // 11 ----------------------[ ' ]---------------------> 12
848+ //
849+ // 12 --------[ 0 to 9, A to F, a to f ]--------------> 12
850+ // 12 ----------------------[ ' ]---------------------> 13
851+ //
847852 // State 1 may be reached by negative numbers.
848853 // State 2 is reached only by hex numbers.
849854 // State 4 is reached only by float numbers.
850855 // State 5 is reached only by numbers in approximate form.
851856 // State 7 is reached only by numbers in bit representation.
857+ // State 11 is reached only by hex string literals (x'...').
852858 // State 10 is a forced proxy to state 4 ensuring a starting dot (= "0.something") precedes a digit, and not "e"
853859 // or "E" causing wrongly interpreted scientific notation (".e[0 to 9]" is invalid). Such invalid notation could
854860 // break the lexer when table names under a given database context starts with ".e[0-9]".
@@ -877,6 +883,8 @@ public function parseNumber()
877883 $ state = 10 ;
878884 } elseif ($ this ->str [$ this ->last ] === 'b ' ) {
879885 $ state = 7 ;
886+ } elseif ($ this ->str [$ this ->last ] === 'x ' || $ this ->str [$ this ->last ] === 'X ' ) {
887+ $ state = 11 ;
880888 } elseif ($ this ->str [$ this ->last ] !== '+ ' ) {
881889 // `+` is a valid character in a number.
882890 break ;
@@ -954,6 +962,29 @@ public function parseNumber()
954962 }
955963 } elseif ($ state === 9 ) {
956964 break ;
965+ } elseif ($ state === 11 ) {
966+ // x'...' hex string literal - expect opening quote
967+ $ flags |= Token::FLAG_NUMBER_HEX_STRING ;
968+ if ($ this ->str [$ this ->last ] !== '\'' ) {
969+ break ;
970+ }
971+
972+ $ state = 12 ;
973+ } elseif ($ state === 12 ) {
974+ // x'...' hex string literal - hex digits or closing quote
975+ if ($ this ->str [$ this ->last ] === '\'' ) {
976+ $ state = 13 ;
977+ } elseif (
978+ ! (
979+ ($ this ->str [$ this ->last ] >= '0 ' && $ this ->str [$ this ->last ] <= '9 ' )
980+ || ($ this ->str [$ this ->last ] >= 'A ' && $ this ->str [$ this ->last ] <= 'F ' )
981+ || ($ this ->str [$ this ->last ] >= 'a ' && $ this ->str [$ this ->last ] <= 'f ' )
982+ )
983+ ) {
984+ break ;
985+ }
986+ } elseif ($ state === 13 ) {
987+ break ;
957988 } elseif ($ state === 10 ) {
958989 $ flags |= Token::FLAG_NUMBER_FLOAT ;
959990 if ($ this ->str [$ this ->last ] < '0 ' || $ this ->str [$ this ->last ] > '9 ' ) {
@@ -966,7 +997,10 @@ public function parseNumber()
966997 $ token .= $ this ->str [$ this ->last ];
967998 }
968999
969- if ($ state === 2 || $ state === 3 || ($ token !== '. ' && $ state === 4 ) || $ state === 6 || $ state === 9 ) {
1000+ if (
1001+ $ state === 2 || $ state === 3 || ($ token !== '. ' && $ state === 4 )
1002+ || $ state === 6 || $ state === 9 || $ state === 13
1003+ ) {
9701004 --$ this ->last ;
9711005
9721006 return new Token ($ token , Token::TYPE_NUMBER , $ flags );
0 commit comments