輸入一條SQL語句,PostgreSQL如何解析輸入的SQL,識(shí)別SQL類型以及基表/字段等信息?接下來的幾節(jié)將逐一進(jìn)行解析.
本節(jié)介紹了開源工具語法分析器Bison.
基本概念
Bison是一個(gè)語法分析器,和Flex配合使用,它可以將用戶提供的語法規(guī)則轉(zhuǎn)化成一個(gè)語法分析器。Flex生成token stream,Bison根據(jù)定義的產(chǎn)生式和動(dòng)作表來解析token stream,從而解析句子.
Bison自定義語法文件,一般以.y作為文件擴(kuò)展名,其格式如下:
%{
Declarations
%}
Definitions
%%
Productions
%%
User subroutines
其中Declarations(聲明)和 User subroutines(用戶自定義過程)和Flex的.l文件是一樣的,Bison會(huì)將這些代碼原樣的拷貝到y(tǒng).tab.c文件中;Definitions(定義)段和Flex類似,也是在這個(gè)段定義一些Bison專有的變量,稍后再解釋這個(gè)文件中的這個(gè)段里的代碼;最重要的是Productions 段,這里面是用戶編寫的語法產(chǎn)生式.
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡(jiǎn)單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:空間域名、虛擬空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、迪慶州網(wǎng)站維護(hù)、網(wǎng)站推廣。
示例
下面用Flex和Bison實(shí)現(xiàn)一個(gè)簡(jiǎn)單的乘法器.
mul.l
詞法文件
%{
#include "y.tab.h"
void yyerror(const char *msg);
void undefined_char(char c);
%}
%%
[0-9]+ { yylval = atoi(yytext); return T_NUMBER; }
[*()\n] { return yytext[0]; }
. { return 0; /* end when meet everything else */ }
%%
int yywrap(void) {
return 1;
}
void undefined_char(char c) {
char buf[32] = "Unrecognized character: ?";
buf[24] = c;
yyerror(buf);
}
void yyerror(const char *msg) {
printf("Error :%s\n", msg);
exit(1);
}
mul.y
語法文件
%{
#include
%}
%token T_NUMBER
%left '*'
%%
S : S E '\n' { printf("result = %d\n", $2); }
| /* empty */ { /* empty */ }
;
E : E '*' E { $$ = $1 * $3; }
| T_NUMBER { $$ = $1; }
;
%%
int main() {
return yyparse();
}
makefile
CC = gcc
OUT = mul
OBJ = lex.yy.o y.tab.o
MUL_L = mul.l
MUL_Y = mul.y
build: $(OUT)
run: $(OUT)
./$(OUT)
clean:
rm -f *.o lex.yy.c y.tab.c y.tab.h y.output $(OUT)
$(OUT): $(OBJ)
$(CC) -o $(OUT) $(OBJ)
lex.yy.c: $(MUL_L) y.tab.c
flex $<
y.tab.c: $(MUL_Y)
bison -vdty $<
執(zhí)行:
[xdb@localhost mul]$ make run
./mul
23*3
result = 69
Bison