怎么理解PostgreSQL的词法分析

66次阅读
没有评论

共计 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 小编将为大家推送更多相关知识点的文章,欢迎关注!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-24发表,共计2574字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)