首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

Mixer SQL 詞法分析器設計:以狀態機實現 Tokenize

     編輯:關於SqlServer

前言

Mixer 專案期望在 Proxy 層提供自訂路由、SQL 黑名單與防禦 SQL 注入等功能,核心基礎在於解析使用者送來的 SQL 語句。這涉及詞法分析與語法分析兩大階段,目前已完成一個簡易的詞法分析器,能將 SQL 拆解為 Token 序列;後續的語法分析與 AST 建構仍在探索中。

詞法分析的常見實作路徑

  • 工具生成法:如 Lex、Yacc,MySQL Proxy 即採用此法。缺點是學習成本高、生成碼可讀性差、體積大,甚至可能較慢,因此 MySQL 官方也選擇自行實作。
  • 正則表達式:雖然直觀,但效能與複雜度皆不容小覷,難以應對 SQL 完整的詞法規則。
  • 狀態機:適合手寫詞法分析器,邏輯清晰、效能佳,Mixer 即採用此方式自行實作。

狀態機設計模式

傳統寫法使用 switch(state) 分派對應的 action,並由 action 回傳下一個 state。隨著 state 增多,case 會膨脹,難以維護。改進方案是採用 State Function:每個 state 即為一個函式,執行完直接回傳下一個 state function,形成鏈式調用。

type stateFn func(*Lexer) stateFn

for state := startState; state != nil; {
    state = state(lexer)
}

Mixer Lexer 核心實作

Lexer 主要對外提供 NextToken() 方法,內部以 channel 暫存解析出的 Token。每個 state function 解析完畢會將 Token 發送至 channel,NextToken 從 channel 取值;若 channel 為空則繼續驅動 state function。

func (l *Lexer) NextToken() (Token, error) {
    for {
        select {
        case t := <-l.tokens:
            return t, nil
        default:
            if l.state == nil {
                return Token{TK_EOF, ""}, l.err
            }
            l.state = l.state(l)
            if l.err != nil {
                return Token{TK_UNKNOWN, ""}, l.err
            }
        }
    }
}

Go 語言的協程與 channel 機制讓這類「生產者-消費者」模式實作極為自然,剩下的工作便是針對 SQL 的關鍵字、標識符、常數、運算子等編寫對應的 state function。

待改進項目

目前對科學記號法數值的解析尚未完善,後續計劃參考 MySQL 官方詞法模組進一步補強。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved