这篇文章主要讲解了“怎么理解PostgreSQL的词法分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解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的词法分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。