共计 2574 个字符,预计需要花费 7 分钟才能阅读完成。
这篇文章主要讲解了“怎么理解 PostgreSQL 的词法分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着丸趣 TV 小编的思路慢慢深入,一起来研究和学习“怎么理解 PostgreSQL 的词法分析”吧!
一、词法分析
基本概念
首先来理清一些基本概念.
词法分析从左向右扫描输入的 SQL 语句,将其字符流分割成一个个的词(称为 token), 这些 token 是输入流中不可再分割的一串字符,类似于英语中单词,或汉语中的词。
SQL 语句中 token 的类别是有限的, 一般来说有常量(数值 / 字符 / 字符串等), 操作符(算术操作符 / 逻辑操作符等), 分隔符(逗号 / 分号 / 括号等), 保留关键字, 标识符(函数名 / 过程名等). 如:1 和 200.13 是数值常量 token,’张三’和’广州市’是字符串常量 token,+/- 等是操作符 token 等.
Flex 简介
在 PostgreSQL 中, 使用了开源的 Flex 对 SQL 进行词法分析.
Flex 全称为 Fast LEXical analyser generator – scanner generator for lexing in C and C++.
Flex 的输入文件格式为:
%{Declarations(声明)
Definitions(定义)
Rules(规则)
User subroutines(用户子过程)
如:
%{
#define T_ZEOR 0
int i = 0;
NUM ([0-9]+)
{NUM} printf( ? // 遇到数字, 打印?
# return T_ZEOR; // 遇到字符 #, 返回 0
. ECHO; // 遇到其他字符, 打印该字符
int main(int argc, char* argv[]) { yylex();
return T_ZEOR;
int yywrap() { return 1;}
该例程的运行效果如下:
[root@localhost mytest]# ./mytest
1t33..q
?t?..q
#
SQL 词法分析器
使用 Flex 可以实现一个简单的 SQL 词法分析器, 简单分为以下几个步骤:
1. 列出 SQL 中所有类型的 token
2. 为每种 token 分配一个唯一的编号, 同时写出该 token 的正则表达式
3. 写出每种 token 的 rule
sql.l
%{
int current_linenum = 1;
void init();
void elog(char* msg, int line);
typedef enum {
T_EQUAL = 128 ,
T_SELECT ,
T_CONST ,
T_STRING ,
T_ID
} TokeType;
static char* string_token[] = {
T_EQUAL , T_SELECT , T_CONST , T_STRING , T_ID
};
INTEGER ([0-9]+)
UNTERM_STRING ([^ \n]*)
STRING ([^ \n]* )
IDENTIFIER ([_a-zA-Z][_a-zA-Z0-9]*)
OPERATOR ([+*-/%=,;! (){}])
SINGLE_COMMENT (// [^\n]*)
[\n] { current_linenum++; }
[ \t\r\a]+ { /* ignore all spaces */ }
{SINGLE_COMMENT} { /* skip for single line comment */ }
{OPERATOR} { return yytext[0]; }
= { return T_EQUAL; }
select { return T_SELECT; }
{INTEGER} { return T_CONST; }
{STRING} { return T_STRING; }
{IDENTIFIER} { return T_ID; }
EOF { return 0; }
{UNTERM_STRING} { elog( Unterminated string constant , current_linenum); }
. { elog( Unrecognized character , current_linenum); }
int main(int argc, char* argv[]) {
int token;
init();
while (token = yylex()) { if(token 128)
printf(%-20c , token);
else
printf(%-20s ,string_token[token - 128]);
puts(yytext);
}
return 0;
void init() {
printf( %-20s%s\n , TOKEN-TYPE , TOKEN-VALUE
printf( -------------------------------------------------\n
void elog(char* msg, int line) { printf( \nError at line %-3d: %s\n\n , line, msg);
int yywrap(void) { return 1;}
makefile
run: sql
./sql test.sql
sql: lex.yy.c
gcc -o $@ $
lex.yy.c: sql.l
flex $
样例 SQL 脚本
select *
from test1
where c1 = TEST
执行结果:
[root@localhost sql]# make
./sql test.sql
TOKEN-TYPE TOKEN-VALUE
-------------------------------------------------
T_SELECT select
* *
T_ID from
T_ID test1
T_ID where
T_ID c1
= =
T_STRING TEST
; ;
感谢各位的阅读,以上就是“怎么理解 PostgreSQL 的词法分析”的内容了,经过本文的学习后,相信大家对怎么理解 PostgreSQL 的词法分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是丸趣 TV,丸趣 TV 小编将为大家推送更多相关知识点的文章,欢迎关注!