zoukankan      html  css  js  c++  java
  • bison 编译sql的基本知识

    一。bison是干什么的?

    bison 是一个语法分析器,把用户输入的内容,根绝在.y文件中事先定义好的规则,构建一课语法分析树。(所谓的规则就是,匹配上对应字符之后,执行相应的动作。)

    1.一个简单的语法例子和分析:

    statement :NAME '=' expression

    expression :NUMBER '+' NUMBER

          |NUMBER '-' NUMBER

    这个语法的意思是:

    冒号(:)用来间隔一条规则的左边和右边。

    statement  等价于   NAME '=' expression   。

    由于在语法中规定大写字母 和引号的内容为终结符,所以NAME '=' 两个字符不再有含义,已经终结。

    但是expression   是非终结符,根据第二行的规定,expression 又等价为 两个数的加法或者两个数的减法。其中竖线(|)表示一个语法符号有两种等价方式。 NUMBER '+' NUMBER   NUMBER '-' NUMBER均是终结符,所以语法解析结束。

    假如现在的输入是fred=12+13.  则语法解析树如下:(圆形都是非终结符,矩形都是终结符)

    2.移进 规约分析

    当bison处理一个语法分析树时,会创建一组状态,每个状态对应一个或者多个分析过的规则中的可能的位置。当读到的记号不足以结束一条规则的时候,就会把这个记号压入一个内部堆栈,然后切换到新状态,这个过程叫做移进。当压入栈内的所有的语法符号已经等价于一个规则的右部时,就把这些符号全部弹出,把规则的左部压入栈。这个过程叫做规约。

    下面是一个例子:

    fred=12+13

    语法分析器一次移进一个记号。

    堆栈:

    fred

    fred =

    fred =12

    fred=12 +

    fred =12+13                 把12+13 规约成expression,12+13弹出,expression压入

    fred = expression     把fred = expression规约成statement   fred = expression弹出,statement压入

    statement

    3.sql语言中的语法解析过程。(以select为例)

    首先,需要一个词法分析器来识别SQL中的所有关键字。

    程序的运行流程:(以select为例)

    1.用户输入sql语句,调用sql.tab.c中的解析函数,得到select_statement的状态。(。y文件中为sql语句定义了好多个状态。)

    2.select_statement作为参数,去匹配规则,并执行相应的动作,即构建一课语法树。这个匹配的过程由yyparse()库函数来完成!

    下面这段代码是.y文件中,定义的关于select_statement部分的代码:

    select_statement:
        SELECT selection table_exp
        {
            struct stnode * p = create_non_terminal_node("select_section");
    
            if(!p)
            {
                printf("error:create_non_terminal_node
    ");
    
                return 1;
            }
    
            if(!append_child(p, $1))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            if(!append_child(p, $2))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            if(!append_child(p, $3))
            {
                printf("error:append_child
    ");
    
                return 1;
            }        
    
            $$ = p;
        }
    selection:
        scalar_exp_list
        {
            struct stnode * p = create_non_terminal_node("selection");
    
            if(!p)
            {
                printf("error:create_non_terminal_node
    ");
    
                return 1;
            }
    
            if(!append_child(p, $1))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            $$ = p;        
        }
        | '*'
        {
            struct stnode * p = create_non_terminal_node("selection");
    
            if(!p)
            {
                printf("error:create_non_terminal_node
    ");
    
                return 1;
            }
    
            if(!append_child(p, $1))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            $$ = p;        
        }
        ;
    scalar_exp_list:
        scalar_exp
        {
            struct stnode * p = create_non_terminal_node("scalar_exp_list");
    
            if(!p)
            {
                printf("error:create_non_terminal_node
    ");
    
                return 1;
            }
    
            if(!append_child(p, $1))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            $$ = p;        
        }
        | scalar_exp_list','scalar_exp
        {
            struct stnode * p = create_non_terminal_node("scalar_exp_list");
    
            if(!p)
            {
                printf("error:create_non_terminal_node
    ");
    
                return 1;
            }
    
            if(!append_child(p, $1))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            if(!append_child(p, $2))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            if(!append_child(p, $3))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            $$ = p;    
        }
        ;
    table_exp:
        from_clause
        opt_order_by_clause
        {
            struct stnode * p = create_non_terminal_node("table_exp");
    
            if(!p)
            {
                printf("error:create_non_terminal_node
    ");
    
                return 1;
            }
    
            if(!append_child(p, $1))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            if(!append_child(p, $2))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            $$ = p;        
        }
        ;
    from_clause:
        FROM table_ref_list opt_where_clause
        {
            struct stnode * p = create_non_terminal_node("from_clause");
    
            if(!p)
            {
                printf("error:create_non_terminal_node
    ");
    
                return 1;
            }
    
            if(!append_child(p, $1))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            if(!append_child(p, $2))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
            
            if(!append_child(p, $3))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            $$ = p;        
        }
        ;
    
    table_ref_list:
        table_ref
        {
            struct stnode * p = create_non_terminal_node("table_ref_list");
    
            if(!p)
            {
                printf("error:create_non_terminal_node
    ");
    
                return 1;
            }
    
            if(!append_child(p, $1))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            $$ = p;        
        }
        | table_ref_list','table_ref
        {
            struct stnode * p = create_non_terminal_node("table_ref_list");
    
            if(!p)
            {
                printf("error:create_non_terminal_node
    ");
    
                return 1;
            }
    
            if(!append_child(p, $1))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            if(!append_child(p, $2))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            if(!append_child(p, $3))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            $$ = p;        
        }
        ;
    table_ref:
        table
        {
            struct stnode * p = create_non_terminal_node("table_ref");
    
            if(!p)
            {
                printf("error:create_non_terminal_node
    ");
    
                return 1;
            }
    
            if(!append_child(p, $1))
            {
                printf("error:append_child
    ");
    
                return 1;
            }
    
            $$ = p;        
        }
        ;

    3.根据上面代码中的定义的规则,,,,展示下面的语法树的构建过程:

    规则                                                                                                   动作:                                                                    语法树

    select_statement  :  SELECT selection table_exp                           node("select_section")                                                  select_statement

                                                                                            SELECT             selection              table_exp

    selection  :  scalar_exp_list                                                          node("selection")                                                                   *

                   |*

    table_exp   :   from_clause       opt_order_by_clause                      node("table_exp")                                                                                from_clause             opt_order_by_clause 

    from_clause:    FROM table_ref_list opt_where_clause                     node("from_clause")                                                      FROM            table_ref_list     opt_where_clause

    table_ref_list  :table_ref   

                        | table_ref_list','table_ref                                         node("table_ref_list  ")                                                                          table_ref  

    table_ref: table                                                                            node("table ")                                                                                         table

  • 相关阅读:
    使用 Spring + CXF 发布 REST 服务
    在web项目中使用CXF暴露REST服务
    学习SpringMVC——从HelloWorld开始
    java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
    安装maven时JAVA_HOME的配置小问题
    java 接口的实现和继承关系
    servlet的两种配置方式
    C# MainWindowHandle为0的解决方法
    C# WindowsMediaPlayer 的一些用法
    C# 获取MP3信息
  • 原文地址:https://www.cnblogs.com/lyr2015/p/6103050.html
Copyright © 2011-2022 走看看