浅谈SQLite——浅析Lemon
1、概述 1.1、分析器接口 ParseAlloc为分析器分配空间,然后初始化它,返回一个指向分析器的指针。SQLite对应的函数为: void*sqlite3ParserAlloc(void*(*mallocProc)(size_t))函数的参数为一个函数指针,并在函数内调用该指针指向的函数。如: 代码 void*(*mallocProc)(size_t)){yyParser*pParser; pParser=(yyParser*)(*mallocProc)((size_t)sizeof(yyParser)); if(pParser){ pParser->yyidx=-1; #ifdefYYTRACKMAXSTACKDEPTH pParser->yyidxMax=0; #endif #ifYYSTACKDEPTH<=0 pParser->yystack=NULL; pParser->yystksz=0; yyGrowStack(pParser); #endif } returnpParser; } 1.1.2、ParseFree SQLite对应的函数如下: 代码 voidsqlite3ParserFree(void*p,/*Theparsertobedeleted*/ void(*freeProc)(void*)Functionusedtoreclaimmemory*/ ){ yyParser*pParser=(yyParser*)p; if(pParser==0)return; while(pParser->yyidx>=0)yy_pop_parser_stack(pParser); #ifYYSTACKDEPTH<=0 free(pParser->yystack); #endif (*freeProc)((void*)pParser); } 1.1.3、Parse void*yyp,0)">Theparserintyymajor,0)">Themajortokencodenumber*/ sqlite3ParserTOKENTYPEyyminorThevalueforthetoken*/ sqlite3ParserARG_PDECLOptional%extra_argumentparameter*/ ) 该函数由sqlite3RunParser调用: 1.2、与yacc和bison的不同之处
expr::=exprTIMESexpr. expr::=LPARENexprRPAREN. expr::=VALUE. 上例中,有一个非终结符“expr”,和5个终结符:“PLUS”、“TIMES”、“LPAREN”、“RPAREN”、和“VALUE”。 而Lemon通过为规则中的每个符号指定一个额外的符号名字(symbolic)达到相同的目的,然后在动作中使用这些符号名字。如下: 2.3、优先级规则(Precedence Rules) 2.4、特殊指示符(Special Directives) %default_destructor %default_type %destructor %extra_argument %include %left %name %nonassoc %parse_accept %parse_failure %right %stack_overflow %stack_size %start_symbol %syntax_error %token_destructor %token_prefix %token_type %type ?%code ?%default_type ?%token_prefix ?%include ?%extra_argument
?%name ?%token_type与%type 通常,每个非终结符都有各自的数据类型。例如,通常非终结符为指向的分析树的根结点的数据类型指针,该根结点包含非终结符的所有信息。例如: 3、SQLite语法规则分析 下面以SELECT语句简要的概述一下SQLite的语法规则。 3.1.2、select-core 相应的语法规则: 代码 cmd::=select(X).{SelectDestdest={SRT_Output,0,128)">0}; sqlite3Select(pParse,X,&dest); sqlite3SelectDelete(pParse->db,X); } %typeselect{Select*}//select语句对应的结构体 %destructorselect{sqlite3SelectDelete(pParse->db,$$);} %typeoneselect{Select*} %destructoroneselect{sqlite3SelectDelete(pParse->db,$$);} select(A)::=oneselect(X).{A=X;} ... 简单SQL语句,可以分成以下几部分:输出列、from子句、where子句、group子句、having子句 oneselect(A)::=SELECTdistinct(D)selcollist(W)from(X)where_opt(Y) groupby_opt(P)having_opt(Q)orderby_opt(Z)limit_opt(L).{ A=sqlite3SelectNew(pParse,W,Y,P,Q,Z,D,L.pLimit,L.pOffset); } ? distinct %typedistinct{int}distinct(A)::=DISTINCT.{A=1;} distinct(A)::=ALL.{A=0;} distinct(A)::=.{A=0;} ?selcollist(输出结果列) 代码 %typeselcollist{ExprList*}输出列对应的结构体%destructorselcollist{sqlite3ExprListDelete(pParse->db,$$);} %typesclp{ExprList*} %destructorsclp{sqlite3ExprListDelete(pParse->db,$$);} sclp(A)::=selcollist(X)COMMA.{A=X;} sclp(A)::=.{A=0;} selcollist(A)::=sclp(P)expr(X)as(Y).{ A=sqlite3ExprListAppend(pParse,X.pExpr); if(Y.n>0)sqlite3ExprListSetName(pParse,A,&Y,128)">1); sqlite3ExprListSetSpan(pParse,&X); } selcollist(A)::=sclp(P)STAR.{ Expr*p=sqlite3Expr(pParse->db,TK_ALL,128)">0); A=sqlite3ExprListAppend(pParse,p); } selcollist(A)::=sclp(P)nm(X)DOTSTAR(Y).{ Expr*pRight=sqlite3PExpr(pParse,&Y); Expr*pLeft=sqlite3PExpr(pParse,TK_ID,&X); Expr*pDot=sqlite3PExpr(pParse,TK_DOT,pLeft,pRight,pDot); } Anoption"AS<id>"phrasethatcanfollowoneoftheexpressionsthat definetheresultset,oroneofthetablesintheFROMclause. AS语句 %typeas{Token} as(X)::=ASnm(Y).{X=Y;} as(X)::=ids(Y).{X=Y;} as(X)::=.{X.n=0;} ?from from子句分以下几部分: single-source: join-op: join-constraint: 语法规则: 代码 %typeseltablist{SrcList*}from子语对应的数据结构%destructorseltablist{sqlite3SrcListDelete(pParse->db,$$);} %typestl_prefix{SrcList*} %destructorstl_prefix{sqlite3SrcListDelete(pParse->db,$$);} %typefrom{SrcList*} %destructorfrom{sqlite3SrcListDelete(pParse->db,$$);} AcompleteFROMclause.FROM子句 // from(A)::=.{A=sqlite3DbMallocZero(pParse->db,255)">sizeof(*A));} from(A)::=FROMseltablist(X).{ A=X; sqlite3SrcListShiftJoinType(A); } "seltablist"isa"SelectTableList"-thecontentoftheFROMclause inaSELECTstatement."stl_prefix"isaprefixofthislist. // stl_prefix(A)::=seltablist(X)joinop(Y).{ A=X; if(ALWAYS(A&&A->nSrc>0))A->a[A->nSrc-1].jointype=(u8)Y; } stl_prefix(A)::=.{A=0;} from后面的语句 seltablist(A)::=stl_prefix(X)nm(Y)dbnm(D)as(Z)indexed_opt(I)on_opt(N)using_opt(U).{ A=sqlite3SrcListAppendFromTerm(pParse,&D,&Z,N,U); sqlite3SrcListIndexedBy(pParse,&I); } 数据库名 %typedbnm{Token} dbnm(A)::=.{A.z=0;A.n=0;} dbnm(A)::=DOTnm(X).{A=X;} 全名 %typefullname{SrcList*} %destructorfullname{sqlite3SrcListDelete(pParse->db,$$);} fullname(A)::=nm(X)dbnm(Y).{A=sqlite3SrcListAppend(pParse->db,&X,&Y);} join语句 %typejoinop{int} %typejoinop2{int} joinop(X)::=COMMA|JOIN.{X=JT_INNER;} joinop(X)::=JOIN_KW(A)JOIN.{X=sqlite3JoinType(pParse,&A,128)">0);} joinop(X)::=JOIN_KW(A)nm(B)JOIN.{X=sqlite3JoinType(pParse,&B,128)">0);} joinop(X)::=JOIN_KW(A)nm(B)nm(C)JOIN. {X=sqlite3JoinType(pParse,&C);} on语句 %typeon_opt{Expr*} %destructoron_opt{sqlite3ExprDelete(pParse->db,$$);} on_opt(N)::=ONexpr(E).{N=E.pExpr;} on_opt(N)::=.{N=NotethatthisblockabusestheTokentypejustalittle.Ifthereis no"INDEXEDBY"clause,thereturnedtokenisempty(z==0&&n==0).If thereisanINDEXEDBYclause,thenthetokenispopulatedaspernormal, withzpointingtothetokendataandncontainingthenumberofbytes inthetoken. Ifthereisa"NOTINDEXED"clause,then(z==0&&n==1),whichis normallyillegal.Thesqlite3SrcListIndexedBy()function recognizesandinterpretsthisasaspecialcase. indexby语句(似乎不属于SQL92标准) %typeindexed_opt{Token} indexed_opt(A)::=.{A.z=0;} indexed_opt(A)::=INDEXEDBYnm(X).{A=X;} indexed_opt(A)::=NOTINDEXED.{A.z=1;} using语句 %typeusing_opt{IdList*} %destructorusing_opt{sqlite3IdListDelete(pParse->db,$$);} using_opt(U)::=USINGLPinscollist(L)RP.{U=L;} using_opt(U)::=.{U=?order by 代码 %typeorderby_opt{ExprList*} %destructororderby_opt{sqlite3ExprListDelete(pParse->db,$$);} %typesortlist{ExprList*} %destructorsortlist{sqlite3ExprListDelete(pParse->db,$$);} %typesortitem{Expr*} %destructorsortitem{sqlite3ExprDelete(pParse->db,0)">orderby语句 orderby_opt(A)::=.{A=0;} orderby_opt(A)::=ORDERBYsortlist(X).{A=X;} sortlist(A)::=sortlist(X)COMMAsortitem(Y)sortorder(Z).{ A=sqlite3ExprListAppend(pParse,Y); if(A)A->a[A->nExpr-1].sortOrder=(u8)Z; } sortlist(A)::=sortitem(Y)sortorder(Z).{ A=sqlite3ExprListAppend(pParse,255)">if(A&&ALWAYS(A->a))A->a[0].sortOrder=(u8)Z; } sortitem(A)::=expr(X).{A=X.pExpr;} 顺序 %typesortorder{int} sortorder(A)::=ASC.{A=SQLITE_SO_ASC;} sortorder(A)::=DESC.{A=SQLITE_SO_DESC;} sortorder(A)::=.{A=SQLITE_SO_ASC;} ?group by 代码 %typegroupby_opt{ExprList*}%destructorgroupby_opt{sqlite3ExprListDelete(pParse->db,$$);} groupby_opt(A)::=.{A=0;} groupby_opt(A)::=GROUPBYnexprlist(X).{A=X;}
having %typehaving_opt{Expr*}%destructorhaving_opt{sqlite3ExprDelete(pParse->db,$$);} having_opt(A)::=.{A=0;} having_opt(A)::=HAVINGexpr(X).{A=X.pExpr;} limit 代码 %typelimit_opt{structLimitVal}Thedestructorforlimit_optwillneverfireinthecurrentgrammar. Thelimit_optnon-terminalonlyoccursattheendofasingleproduction ruleforSELECTstatements.Assoonastherulethatcreatethe limit_optnon-terminalreduces,theSELECTstatementrulewillalso reduce.Sothereisneveralimit_optnon-terminalonthestack exceptasatransient.Sothereisneveranythingtodestroy. %destructorlimit_opt{ sqlite3ExprDelete(pParse->db,$$.pLimit); } limit_opt(A)::=.{A.pLimit=0;A.pOffset=0;} limit_opt(A)::=LIMITexpr(X).{A.pLimit=X.pExpr;A.pOffset=0;} limit_opt(A)::=LIMITexpr(X)OFFSETexpr(Y). {A.pLimit=X.pExpr;A.pOffset=Y.pExpr;} limit_opt(A)::=LIMITexpr(X)COMMAexpr(Y). {A.pOffset=X.pExpr;A.pLimit=Y.pExpr;} 主要参考: http://www.sqlite.org/src/doc/trunk/doc/lemon.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |