Heim > Datenbank > MySQL-Tutorial > mixer:sql词法分析器设计

mixer:sql词法分析器设计

WBOY
Freigeben: 2016-06-07 16:20:24
Original
1180 Leute haben es durchsucht

您现在的位置:首页>教程>编程开发>mssql数据库 > mixer:sql词法分析器设计 mixer:sql词法分析器设计 感谢 3lian8 的投递 时间:2014-03-25 来源:三联教程 介绍 mixer希望在proxy这层就提供自定义路由,sql黑名单,防止sql注入攻击等功能,而这些的基石就在

  您现在的位置:首页 > 教程 > 编程开发 > mssql数据库 > mixer:sql词法分析器设计

mixer:sql词法分析器设计

感谢 3lian8 的投递 时间:2014-03-25 来源:三联教程 

   介绍

  mixer希望在proxy这层就提供自定义路由,sql黑名单,防止sql注入攻击等功能,而这些的基石就在于将用户发上来的sql语句进行解析。也就是我最头大的词法分析和语法分析。

  到现在为止,我只是实现了一个比较简单的词法分析器,用以将sql语句分解成多个token。而对于从token在进行语法分析,构建sql的AST,,我现在还真没啥经验(编译原理太差了),急需牛人帮忙。

  所以,这里只是简单介绍一下mixer的词法分析。

  tokenize

  在很多地方,我们都需要进行词法分析,通常会有几种方式:

  使用一个强大的工具,譬如lex,mysql-proxy就用的这种方式

  使用正则表达式

  state machine

  对于使用工具,我觉得有一个不怎么好的地方在于学习成本,譬如我用lex的时候就需要学习它的语法,同时通过工具生成的代码可读性都不怎么好,代码量大,更严重的是可能会比较慢。所以mysql自身也是自己实现一个词法分析模块。

  而对于正则表达式,性能问题可能是一个很需要考虑的,而且复杂度并不比使用类似lex这样的工具低。

  状态机可能是我觉得自己动手实现词法解析一个很好的方式,对于sql的词法解析,我觉得使用state machine的方式来自己写一个难度并不大,所以mixer自己实现了一个。

  state machine

  通常,一个状态机的实现采用的是state + action + switch的做法,可能如下:

?

1

2

3

4

5

6

7

8

switch state {

    case state1:

        state = action1()

    case state2:

        state = action2()

    case state3:

        state = action3()

}

  对于一个state,我们通过switch知道它将会由哪一个action进行处理,而对于每一个action,我们则知道执行完成之后下一个state是什么。

  对于上面的实现,如果state过多,可能会导致太多的case语句,我们可以通过state function进行简化。

  一个state function就是执行当前的state action,并且直接返回下一个state function。

  我们可以这样做:

?

1

2

3

4

5

type stateFn func(*Lexer) stateFn

 

for state := startState; state != nil {

    state = state(lexer)

}

  所以我们需要实现的就是每一个state function以及对应的它的下一个需要执行的state function。

  mixer lexer

  mixer的词法分析实现主要参考这个。主要实现在parser模块。

  对于一个lexer,需要提供的是NextToken的功能,供外部获取下一个token,从而进行后续的操作(譬如语法分析)。

  lexer的next token如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

func (l *Lexer) NextToken() (Token, error) {

    for {

        select {

            case t :=

                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

                }

        }

    }

}

  tokens是一个channel,每次state解析的token都会emit到这个channel上面,供NextToken获取,如果channel为空了,则再次调用state function。

  可以看到,用go实现一个词法解析是很容易的事情,剩下的就是写相应的state function用来解析sql。

  todo

  mixer的词法分析还有很多不完善的地方,譬如对于科学计数法数值的解析就不完善,后续准备参考mysql官方的词法分析模块在好好完善一下。

相关文章

  • 上一篇:pl/sqldeveloper执行光标所在行
  • 下一篇:SQLSERVER中PERCENTILE_CONT和PERCENTILE_DISC
  • 标签:

    [返回三联首页] [返回mssql数据库栏目] / [加入三联文集]

    Verwandte Etiketten:
    Quelle:php.cn
    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
    Beliebte Tutorials
    Mehr>
    Neueste Downloads
    Mehr>
    Web-Effekte
    Quellcode der Website
    Website-Materialien
    Frontend-Vorlage