2.2.2 字面值解析逻辑
如果在实现中,通过没有跳出 CASE
语句逻辑,继续执行另一个状态的处理逻辑,则在描述中将这种情况也描述为重置了自动机状态以方便理解。
2.2.2.1 二进制字面值
对于格式为 [bB]'[01]*'
的二进制字面值,其解析逻辑如下:
MY_LEX_START
:初始状态,遇到b
或B
时,通过state_map
映射,将自动机状态置为MY_LEX_IDENT_OR_BIN
。MY_LEX_IDENT_OR_BIN
:如果下一个字符是'
则将自动机状态置为MY_LEX_BIN_NUMBER
,否则将自动机状态置为MY_LEX_IDENT
。MY_LEX_BIN_NUMBER
:不断匹配0
和1
直至遇到其他字符,如果之后的字符是'
则构造 Token 并返回BIN_NUM
类型,否则返回ABORT_SYM
抛出异常。
对于格式为 0b[0-1]+
的二进制字面值,其解析逻辑如下:
MY_LEX_START
:初始状态,遇到0
时,通过state_map
映射,将自动机状态置为MY_LEX_NUMBER_IDENT
。MY_LEX_NUMBER_IDENT
:如果下一个字符是b
,不断匹配0
和1
直至遇到其他字符,构造 Token 并返回BIN_NUM
类型。
2.2.2.2 十六进制字面值
对于格式为 [xX]'[A-Fa-f0-9]*'
的十六进制字面值,其解析逻辑如下:
MY_LEX_START
:初始状态,遇到x
或X
时,通过state_map
映射,将自动机状态置为MY_LEX_IDENT_OR_HEX
。MY_LEX_IDENT_OR_HEX
:如果下一个字符是'
则将自动机状态置为MY_LEX_HEX_NUMBER
,否则将自动机状态置为MY_LEX_IDENT
MY_LEX_HEX_NUMBER
:不断匹配十六进制字符直至遇到其他字符,即大写A
到F
、小写a
到f
或数字,则构造 Token 并返回HEX_NUM
类型,否则返回ABORT_SYM
抛出异常
对于格式为 0b[A-Fa-f0-9]+
的二进制字面值,其解析逻辑如下:
MY_LEX_START
:初始状态,遇到0
时,通过state_map
映射,将自动机状态置为MY_LEX_NUMBER_IDENT
。MY_LEX_NUMBER_IDENT
:如果下一个字符是x
,不断匹配十六进制字符直至遇到其他字符,构造 Token 并返回HEX_NUM
类型。
2.2.2.3 Unicode 字符串字面值
Unicode 字符串字面值的格式为 [nN]'string'
,其中 string
中允许出现转义符,其解析逻辑如下:
MY_LEX_START
:初始状态,遇到n
或N
时,通过state_map
映射,将自动机状态置为MY_LEX_IDENT_OR_NCHAR
。MY_LEX_IDENT_OR_NCHAR
:如果下一个字符不是'
则将自动机状态置为MY_LEX_IDENT
;否则,调用get_text
函数匹配字符串字面值中引号内的部分,构造 Token 并返回NCHAR_STRING
类型
2.2.2.4 字符串字面值
字符串字面值的格式为 'string'
,其中 string
中允许出现转义符,其解析逻辑如下:
MY_LEX_START
:初始状态,遇到'
时,通过state_map
映射,将自动机状态置为MY_LEX_STRING
。MY_LEX_STRING
:调用get_text
函数字面值中引号内的部分,构造 Token 并返回TEXT_STRING
类型。
如果 sql_mode
没有开启 MODE_ANSI_QUOTES
,则支持双引号字符串,其解析逻辑如下:
MY_LEX_START
:初始状态,遇到"
时,通过state_map
映射,将自动机状态置为MY_LEX_STRING_OR_DELIMITER
。MY_LEX_STRING_OR_DELIMITER
:如果sql_mode
开启了MODE_ANSI_QUOTES
,则将状态置为MY_LEX_USER_VARIABLE_DELIMITER
,否则将状态置为MY_LEX_STRING
MY_LEX_STRING
:逻辑与普通字符串字面值一致。
2.2.2.5 整数字面值
整数字面值的解析逻辑如下:
MY_LEX_START
:初始状态,遇到数字时,通过state_map
映射,将自动机状态置为MY_LEX_NUMBER_IDENT
。MY_LEX_NUMBER_IDENT
:如果开头字符不是0
或下一个字符不是b
或x
,则继续不断匹配数字直至遇到其他字符;通过ident_map
映射,如果下一个字符不是标识符的组成元素,即当前语法元素不是标识符,则将自动机状态置为MY_LEX_INT_OR_REAL
;MY_LEX_INT_OR_REAL
:如果下一个字符不是.
,则调用get_token
函数构造 Token 并调用int_token
函数构造返回值类型
2.2.2.6 浮点字面值
以 [0-9]+[eE]
开头的浮点数字面值的解析逻辑如下:
MY_LEX_START
:初始状态,遇到数字时,通过state_map
映射,将自动机状态置为MY_LEX_NUMBER_IDENT
。MY_LEX_NUMBER_IDENT
:如果开头字符不是0
或下一个字符不是b
或x
,则继续不断匹配数字直至遇到其他字符。下一个字符是e
或E
,且下一个元素是数字或+
、-
,如果是+
、-
下一个元素是数字,则构造 Token 并返回FLOAT_NUM
类型;如果下一个字符不是e
或E
,则将自动机状态置为MY_LEX_IDENT_START
继续当作标识符进行解析。
以 [0-9]+.
开头的浮点数字面值的解析逻辑如下:
MY_LEX_START
:初始状态,遇到数字时,通过state_map
映射,将自动机状态置为MY_LEX_NUMBER_IDENT
。MY_LEX_NUMBER_IDENT
:如果开头字符不是0
或下一个字符不是b
或x
,则继续不断匹配数字直至遇到其他字符;通过ident_map
映射,如果下一个字符不是标识符的组成元素,即当前语法元素不是标识符,则将自动机状态置为MY_LEX_INT_OR_REAL
;MY_LEX_INT_OR_REAL
:下一个字符是.
,将自动机状态重置为MY_LEX_REAL
MY_LEX_REAL
:先解析剩余的数字(小数部分),然后尝试解析e
或E
,如果解析到e
或E
则构造 Token 返回FLOAT_NUM
类型,否则返回DECIMAL_NUM
类型。
以 .
开头的浮点数字面值的解析逻辑如下:
MY_LEX_START
:当前字符为.
,通过state_map
映射,将自动机状态置为MY_LEX_REAL_OR_POINT
。MY_LEX_REAL_OR_POINT
:下一个字符为数字,将自动机状态置为MY_LEX_REAL
。MY_LEX_REAL
:先解析剩余的数字(小数部分),然后尝试解析e
或E
,如果解析到e
或E
则构造 Token 返回FLOAT_NUM
类型,否则返回DECIMAL_NUM
类型。