從 TiDB 簡單理解 Lex Yacc

2021-10-08 18:40:57 字數 3971 閱讀 6732

它們能夠讓你更容易的解析複雜的語言,達成解析字串的目的。

輸入字元流 ,發現某一段字元能夠匹配乙個關鍵字,就根據定義好的動作來執行。

%

%begin printf

("begin;\n");

executesql printf

("select * from t1;\n"

);

commit printf

("commit;\n");

%%

lex 的每一段是通過%%分割的,這裡設定了 3 個關鍵字 :

begin

executesql

commit

讀取字元流時,遇到關鍵字 ,就會根據後面的指令去執行動作。比如遇到executesql,會列印select * from t1 ;如果匹配不到關鍵字 ,會正常輸出。

[2020/07/31 09:43:01] 

[info]

[server.go:391]

["connection closed"]

[conn=4]

根據日誌中的元素,定義如下關鍵字

word > connection|conn|info|closed

date >

2020/07

/3109:

43:01filename > server.go

num >

391|4

leftbracket >

[rightbracket >

]colon >

:slash >

/equalsign >

=quotationmark > "

lex 分詞器

%

%[a−za−z]

[a−za−z0−9]*

return word

日期的正規表示式.手動狗頭 return date

\[a−za−z0−9\/

.−]+

return filename

\[0123456789]+

return num

\[return leftbracket

\]return rightbracket

\:return colon

\/return slash

\=return equalsign

\" return quotationmark

%%

經過 lex 分詞的結果就是

leftbracket date rightbracket

leftbracket word rightbracket

leftbracket filename colon num rightbracket

leftbracket quotationmark word word quotationmark rightbracket

leftbracket word equalsign num rightbracket

tidb中,類似的結構都存放在parser.y中,

結構如下,

第一部分主要是定義token的型別、優先順序、結合性等。

%

%union

ident string

expr ast.exprnode

statement ast.stmtnode

}%token

%type

%precedence empty

%left join straightjoin inner cross left right full natural

%start start

通過%%分割,以上是第一部分,即定義段

%%
下部分是 sql 語法的產生式和每個規則對應的 action ,我們找乙個簡單的看看,

這應該是drop table的 分詞結構,生成ast.droptablestmt語法樹來執行

droptablestmt:

"drop" opttemporary tableortables ifexists tablenamelist restrictorcascadeopt

}

這裡有 5 個 token ,分別是

opttemporary

tableortables

ifexists

tablenamelist

restrictorcascadeopt

分別看一下這些 token 的定義,那兩個 table 巴拉巴拉就不看了

opttemporary

//應該是臨時表的 token ,如果有這個 token ,則會被解析。

//但也如邏輯中寫的,「tidb 目前不支援臨時表,雖然會被解析,但是不生效。」

opttemporary:

/* empty */

|"temporary"

if exists

// 是否有 if exists

ifexists:

|"if"

"exists"

restrict: 確保只有不存在相關檢視和完整性約束的表才能刪除

cascade: 任何相關檢視和完整性約束都將一併被刪除

restrictorcascadeopt:

{}| "restrict"

| "cascade"

所以可以看出,在drop table的時候,在這個語法結構中," 豐滿 " 的語句大概是

drop temporary table ifexists tablename restrict/cascade
之後就會生成一棵 ast 抽象語法ast.droptablestmt

ast/ddl.

gotype droptablestmt struct

這個具體的實現,比如這個

func

(n *droptablestmt)

restore

(ctx *format.restorectx)

error

else

else

}if n.ifexists

for index, table :=

range n.tables

if err := table.

restore

(ctx)

; err !=

nil}

return

nil}

先判斷了drop的是view還是table, 如果走進了table分支,也就大概判斷了是否是臨時表,是否有各種特殊的語法。

到這裡基本了解了 tidb 中對於 sql 解析的方式,當然,和行文的區別, tidb 用的是goyacc,不過好像區別也不是很大,這篇希望可以給大家乙個參考。

TiDB基本架構簡單總結

和mysql不同,tidb是乙個分布式的資料庫而不是單個程序,所以整個tidb是由以下角色組成 tikv,pd,tidb,tispark。每個角色都是部署在多台機器上的程序組成的集群。tikv負責資料的儲存,對外而言,它就是乙個提供key value儲存的引擎。但它儲存的並不是離散的key,而在乙個...

從0理解設計模式《簡單工廠》

我在開始寫程式的時候經常會遇到一種情況,例如更改乙個字段,或者新增乙個小功能,就會把之前的廢棄掉,重寫單獨開乙個類,然後增加變數,方法 貼上複製那種 結果就單單改了其中的乙個功能而已,耗時耗力,如果你也遇到這種情況,那麼說明非常需要學習下設計模式了。我認為設計模式是 一種思想,一種模式,一種套路,一...

TiDB全量遷移,從MySql遷移到tidb

mydumper是乙個強大的資料遷移工具,具體可以參考 maxbube mydumper。你可以使用mydumper從 mysql 匯出資料,然後用 loader 將其匯入到 tidb。注意 雖然 tidb 也支援使用 mysql 官方的mysqldump工具來進行資料的遷移工作,但相比於mydum...