使用flex和bison實現的sql引擎解析

2021-06-23 02:26:43 字數 4360 閱讀 6102

由於老師要求,最近在做oceanbase儲存過程的實現,在oceanbase 0.4以前是不支援儲存過程的。實現的主要步驟主要包括

現在先來說說語法解析吧,在這一塊主要是使用的flex( 詞法分析器生成工具) 和bison(語法分析器生成器) 這兩個是對使用者輸入的儲存過程語句進行解析的

來具體說說該怎麼實現對sql語句的分析吧

1、首先建立乙個lex的檔案

%option noyywrap nodefault yylineno case-insensitive

%%x comment

%%create

procedure

sql

declare

set

begin

end

int

varchar

date

time

double

if

then

else

endif

for

when

while

[0-9]+ /*number*/

[0-9]+"."[0-9]* |

"."[0-9]+ |

[0-9]+e[-+]?[0-9]+ |

[0-9]+"."[0-9]*e[-+]?[0-9]+ |

true /*bool*/

false /*bool*/

'(\\.|''|[^'\n])*' |

\"(\\.|\"\"|[^"\n])*\" /*string*/

'(\\.|[^'\n])*$

\"(\\.|[^"\n])*$

x'[0-9a-f]+' |

0x[0-9a-f]+

0b[01]+ |

b'[01]+'

[-+&~|^/%*(),.;!]

"&&"

"||"

"">"

"!=" |

"<>"

"="

"<="

">="

"<=>"

"<

">>"

[a-za-z][a-za-z0-9_]*

`[^`/\\.\n]+`

`[^`\n]*$

@[0-9a-z_.$]+ |

@\"[^"\n]+\" |

@`[^`\n]+` |

@'[^'\n]+'

@\"[^"\n]*$

@`[^`\n]*$

@'[^'\n]*$

":="

#.* ;

"--"[ \t].* ;

"/*"

"*/"

.|\n ;

<>

[ \t\n] /* white space */

.

%%

這一部分呢就是對 每個我們自定義的滿足正則的識別

接下來是對詞的語法識別

%

%}%locations

%union

%token name

%token string

%token intnum

%token bool

%token uservar

%type stmt_root create_stmt para_list definition data_type pro_block pro_parameters declare_list set_list

%type assign_var pro_body pro_stmt_list sql_stmt expr

%right assign

%left or

%left xor

%left andop

%left not '!'

%left between

%left comparison /* = <> < > <= >= <=> */

%left '|'

%left '&'

%left shift /* << >> */

%left '+' '-'

%left '*' '/' '%' mod

%left '^'

%token create

%token procedure

%token proname

%token declare

%token set

%token begint

%token end

%token sql

%token int

%token varchar

%token date

%token time

%token double

%token if

%token not

%token exists

%token then

%token else

%token endif

%token for

%token when

%token while

%start stmt_root

%%stmt_root: create_stmt pro_block

;create_stmt: create procedure name '(' para_list ')' ;

/*opt_if_not_exists:

| if not exists

;*/para_list: definition

|definition ',' para_list ;

definition: uservar data_type ;

data_type:

date

| time

| varchar '(' intnum ')'

| int

| double

;pro_block: begint pro_parameters pro_body end ;

pro_parameters: declare_list ';'

|pro_parameters declare_list ';'

|pro_parameters set_list ';' ;

declare_list:

|declare definition

|declare_list ',' definition ;

set_list:

|set assign_var

| set_list ',' assign_var ;

assign_var : uservar comparison expr ;

expr: name

| string

| intnum

| bool

;pro_body : pro_stmt_list

;pro_stmt_list: sql_stmt

|pro_stmt_list sql_stmt ;

sql_stmt:

|sql name ';' ;%%

/*int main(int argc, char* argv)

*/int readinputforlexer( char *buffer, int *numbytesread, int maxbytestoread )

for ( i = 0; i < numbytestoread; i++ )

*numbytesread = numbytestoread;

globalreadoffset += numbytestoread;

return 0;

}void yyerror(const char *s, ...)

void zzerror(const char *s, ...)

int yywrap(void)

char* getsql()

這部分就是對上乙個識別出來的詞 進行順序上的確定,構成乙個完整的語法

這些需要在linux環境下進行除錯

bison -d 檔名

flex 檔名

使用bison和flex工具 zz

這裡有乙個使用bison建立乙個簡單的計算器的例子 使用bison和flex工具學習編譯原理,遠比單獨看書然後自己編寫一些程式生動的多。這樣你就不會在那些複雜的字元處理,正規表示式的處理上浪費精力,最後費盡心力,卻沒有結果,失去了學習的興趣。我這裡有乙個簡單的計算器的程式,可以實現加 減 乘 除運算...

程式中,呼叫Bison和Flex結合的小例子

網上的很多程式,對初次接觸bison和flex的人而言,都有點複雜,看最簡單的例子更好些 我稍微修改一下,說說自己的理解,也作為乙個備忘 flex程式 1 root lex total cat lexer.l 2 12 13 digit 0 9 14 1516 17 18 19 2021 22voi...

利用 flex 和 bison 寫乙個計算器

實現實數範圍內的加減乘除 乘方 開方,三角函式sin cos運算 a 在命令提示符下依次執行一下兩行命令 flex 檔名.lex bison o檔名.c 檔名.y編譯的話,可用命令提示符,不過需要自己搭建環境 gcc o 可執行程式名稱 lex.yy.c bison生成的檔名.c當然可以用其他的方法...