@@ -833,11 +833,17 @@ public function parseNumber()
833833 //
834834 // 10 -------------------[ 0 to 9 ]-------------------> 4
835835 //
836+ // 11 ----------------------[ ' ]---------------------> 12
837+ //
838+ // 12 --------[ 0 to 9, A to F, a to f ]--------------> 12
839+ // 12 ----------------------[ ' ]---------------------> 13
840+ //
836841 // State 1 may be reached by negative numbers.
837842 // State 2 is reached only by hex numbers.
838843 // State 4 is reached only by float numbers.
839844 // State 5 is reached only by numbers in approximate form.
840845 // State 7 is reached only by numbers in bit representation.
846+ // State 11 is reached only by hex string literals (x'...').
841847 // State 10 is a forced proxy to state 4 ensuring a starting dot (= "0.something") precedes a digit, and not "e"
842848 // or "E" causing wrongly interpreted scientific notation (".e[0 to 9]" is invalid). Such invalid notation could
843849 // break the lexer when table names under a given database context starts with ".e[0-9]".
@@ -866,6 +872,8 @@ public function parseNumber()
866872 $ state = 10 ;
867873 } elseif ($ this ->str [$ this ->last ] === 'b ' ) {
868874 $ state = 7 ;
875+ } elseif ($ this ->str [$ this ->last ] === 'x ' || $ this ->str [$ this ->last ] === 'X ' ) {
876+ $ state = 11 ;
869877 } elseif ($ this ->str [$ this ->last ] !== '+ ' ) {
870878 // `+` is a valid character in a number.
871879 break ;
@@ -949,6 +957,29 @@ public function parseNumber()
949957 }
950958 } elseif ($ state === 9 ) {
951959 break ;
960+ } elseif ($ state === 11 ) {
961+ // x'...' hex string literal - expect opening quote
962+ $ flags |= Token::FLAG_NUMBER_HEX_STRING ;
963+ if ($ this ->str [$ this ->last ] !== '\'' ) {
964+ break ;
965+ }
966+
967+ $ state = 12 ;
968+ } elseif ($ state === 12 ) {
969+ // x'...' hex string literal - hex digits or closing quote
970+ if ($ this ->str [$ this ->last ] === '\'' ) {
971+ $ state = 13 ;
972+ } elseif (
973+ ! (
974+ ($ this ->str [$ this ->last ] >= '0 ' && $ this ->str [$ this ->last ] <= '9 ' )
975+ || ($ this ->str [$ this ->last ] >= 'A ' && $ this ->str [$ this ->last ] <= 'F ' )
976+ || ($ this ->str [$ this ->last ] >= 'a ' && $ this ->str [$ this ->last ] <= 'f ' )
977+ )
978+ ) {
979+ break ;
980+ }
981+ } elseif ($ state === 13 ) {
982+ break ;
952983 } elseif ($ state === 10 ) {
953984 $ flags |= Token::FLAG_NUMBER_FLOAT ;
954985 if ($ this ->str [$ this ->last ] < '0 ' || $ this ->str [$ this ->last ] > '9 ' ) {
@@ -961,7 +992,7 @@ public function parseNumber()
961992 $ token .= $ this ->str [$ this ->last ];
962993 }
963994
964- if ($ state === 2 || $ state === 3 || ($ token !== '. ' && $ state === 4 ) || $ state === 6 || $ state === 9 ) {
995+ if ($ state === 2 || $ state === 3 || ($ token !== '. ' && $ state === 4 ) || $ state === 6 || $ state === 9 || $ state === 13 ) {
965996 --$ this ->last ;
966997
967998 return new Token ($ token , Token::TYPE_NUMBER , $ flags );
0 commit comments