📄 parse.y
字号:
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
if( pParse->zErrMsg==0 ){
if( TOKEN.z[0] ){
eDbErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
}else{
eDbErrorMsg(pParse, "incomplete SQL statement");
}
}
}
%name Parser
%include {
#include "eDbInit.h"
#include "parse.h"
} // end %include
// These are extra tokens used by the lexer but never seen by the
// parser. We put them in a rule so that the parser generator will
// add them to the parse.h output file.
//
%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
COLUMN AGG_FUNCTION.
// Input is a single SQL command
input ::= ecmd.
ecmd ::= explain cmdx SEMI.
ecmd ::= SEMI.
cmdx ::= cmd. {eDbExec(pParse); }
explain ::= . {eDbBeginParse(pParse, 0); }
///////////////////// The CREATE TABLE statement ////////////////////////////
//
cmd ::= create_table create_table_args.
create_table ::= CREATE(X) TABLE nm(Y). {eDbStartTable(pParse,&X,&Y);}
create_table_args ::= LP columnlist RP(X). {eDbEndTable(pParse,&X);}
columnlist ::= columnlist COMMA column.
columnlist ::= column.
column ::= columnid type .
columnid ::= nm(X). {eDbAddColumn(pParse,&X);}
%left OR.
%left AND.
%left EQ NE.
%left GT GE LT LE.
%left PLUS MINUS.
%left LSHIFT RSHIFT.
%type ids {Token}
ids(A) ::= ID(X). {A = X;}
ids(A) ::= STRING(X). {A = X;}
// The name of a column or table can be any of the following:
//
%type nm {Token}
nm(A) ::= ID(X). {A = X;}
nm(A) ::= STRING(X). {A = X;}
nm(A) ::= JOIN_KW(X). {A = X;}
type ::= .
type ::= typename(X). {eDbAddColumnType(pParse,&X,&X);}
type ::= typename(X) LP signed RP(Y). {eDbAddColumnType(pParse,&X,&Y);}
type ::= typename(X) LP signed COMMA signed RP(Y).
{eDbAddColumnType(pParse,&X,&Y);}
%type typename {Token}
typename(A) ::= ids(X). {A = X;}
typename(A) ::= typename(X) ids. {A = X;}
%type signed {int}
signed(A) ::= INTEGER(X). { A = atoi(X.z); }
signed(A) ::= PLUS INTEGER(X). { A = atoi(X.z); }
signed(A) ::= MINUS INTEGER(X). { A = -atoi(X.z); }
///////////////////// The DROP TABLE statement ////////////////////////////
//
cmd ::=DROP TABLE nm(X). {eDbDropTable(pParse,&X,0);}
///////////////////// The CREATE INDEX statement ////////////////////////////
//
cmd ::= CREATE(S) INDEX nm(X) ON nm(Y) LP idxlist(Z) RP(E). {
eDbCreateIndex(pParse,&X,eDbSrcListAppend(0,&Y,0),Z,OE_None,&S,&E);
}
%type idxlist {IdList*}
%destructor idxlist {eDbIdListDelete($$);}
%type idxitem {Token}
idxlist(A) ::= idxlist(X) COMMA nm(Y). {A = eDbIdListAppend(X,&Y);}
idxlist(A) ::= nm(Y). {A = eDbIdListAppend(0,&Y);}
///////////////////// The DROP INDEX statement ////////////////////////////
//
cmd ::= DROP INDEX nm(X) . {eDbDropIndex(pParse,eDbSrcListAppend(0,&X,0));}
///////////////////// The INSERT statement ////////////////////////////
//
cmd ::= INSERT INTO nm(X) inscollist_opt(F) VALUES LP itemlist(Y) RP. {
eDbInsert(pParse,eDbSrcListAppend(0,&X,0),Y,0,F,0);
}
%type itemlist {ExprList *}
%destructor itemlist {eDbExprListDelete($$);}
itemlist(A) ::= itemlist(X) COMMA expr(Y). {A = eDbExprListAppend(X,Y,0);}
itemlist(A) ::= expr(X). {A = eDbExprListAppend(0,X,0);}
%type inscollist_opt {IdList *}
%destructor inscollist_opt {eDbIdListDelete($$);}
%type inscollist {IdList *}
%destructor inscollist {eDbIdListDelete($$);}
inscollist_opt(A) ::= . {A = 0;}
inscollist_opt(A) ::= LP inscollist(X) RP. {A = X;}
inscollist(A) ::= inscollist(X) COMMA nm(Y). {A = eDbIdListAppend(X,&Y);}
inscollist(A) ::= nm(Y). {A = eDbIdListAppend(0,&Y);}
///////////////////// The DELETE statement ////////////////////////////
//
cmd ::= DELETE FROM nm(X) where_opt(Y). {eDbDeleteFrom(pParse,eDbSrcListAppend(0,&X,0),Y);}
%type where_opt {Expr *}
%destructor where_opt {eDbExprDelete($$);}
where_opt(A) ::=. {A = 0;}
where_opt(A) ::= WHERE expr(X). {A = X;}
///////////////////// The UPDATE statement ////////////////////////////
//
cmd ::= UPDATE nm(X) SET setlist(Y) where_opt(Z). {eDbUpdate(pParse,eDbSrcListAppend(0,&X,0),Y,Z);}
%type setlist {IdExprList *}
%destructor setlist {eDbIdExprListDelete($$);}
setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y). {A = eDbIdExprListAppend(Z,Y,&X);}
setlist(A) ::= nm(X) EQ expr(Y). {A = eDbIdExprListAppend(0,Y,&X);}
///////////////////// The SELECT statement ////////////////////////////
// SELECT [tbl_name.]*|[tbl_name.]colname [AS alias][,[tbl_name.]colname [AS alias],...]
// FROM tbl_name [AS alias] [,tbl_name [AS alias]...]
// WHERE [tbl_name.]colname OP [tbl_name.]colname|NUMBER|STRING [AND|OR [tbl_name.]colname OP [tbl_name.]colname|NUMBER|STRING ...]
// OP {>,<,=,>=,<=,!=}
cmd ::= SELECT distinct(D) selcollist(W) FROM seltablist(X) where_opt(Y) group_opt(P) having_opt(Q) orderby_opt(Z). {{
Select *pS = eDbSelectNew(W,X,Y,P,Q,Z,D);
eDbSelect(pParse,pS);
}}
%type distinct {int}
distinct(A) ::= DISTINCT. {A = 1;}
distinct(A) ::= ALL. {A = 0;}
distinct(A) ::= . {A = 0;}
%type selcollist {ExprList *}
%destructor selcollist {eDbExprListDelete($$);}
%type sclp {ExprList *}
%destructor sclp {eDbExprListDelete($$);}
sclp(A) ::= selcollist(X) COMMA. {A = X;}
sclp(A) ::=. {A = 0;}
selcollist(A) ::= sclp(P) expr(X) as(Y). {A = eDbExprListAppend(P,X,Y.n?&Y:0);}
selcollist(A) ::= sclp(P) STAR. {A = eDbExprListAppend(P,eDbExpr(TK_ALL,0,0,0),0);}
selcollist(A) ::= sclp(P) nm(X) DOT STAR. {{
Expr *pRight = eDbExpr(TK_ALL,0,0,0);
Expr *pLeft = eDbExpr(TK_ID,0,0,&X);
A = eDbExprListAppend(P,eDbExpr(TK_DOT,pLeft,pRight,0),0);
}}
%type as {Token}
as(A) ::= AS nm(X). {A = X;}
as(A) ::= ids(X). {A = X;}
as(A) ::= . {A.n = 0;}
%type seltablist {SrcList *}
%destructor seltablist {eDbSrcListDelete($$);}
seltablist(A) ::= seltablist(X) COMMA nm(Y) as(Z). {{
A = eDbSrcListAppend(X,&Y,0);
if( Z.n ) eDbSrcListAddAlias(A,&Z);
}}
seltablist(A) ::= nm(X) as(Y). {{
A = eDbSrcListAppend(0,&X,0);
if( Y.n ) eDbSrcListAddAlias(A,&Y);
}}
%type group_opt {ExprList *}
%destructor group_opt {eDbExprListDelete($$);}
group_opt(A) ::= . {A = 0;}
group_opt(A) ::= GROUP BY exprlist(X). {A = X;}
%type having_opt {Expr *}
%destructor having_opt {eDbExprDelete($$);}
having_opt(A) ::= . {A = 0;}
having_opt(A) ::= HAVING expr(X). {A = X;}
%type orderby_opt {ExprList *}
%destructor orderby_opt {eDbExprListDelete($$);}
%type sortlist {ExprList *}
%destructor sortlist {eDbExprListDelete($$);}
%type sortorder {int}
orderby_opt(A) ::= . {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
sortlist(A) ::= sortlist(X) COMMA expr(Y) sortorder(Z). {{
A = eDbExprListAppend(X,Y,0);
if(A) A->a[0].sortOrder = Z;
}}
sortlist(A) ::= expr(Y) sortorder(Z). {{
A = eDbExprListAppend(0,Y,0);
if(A) A->a[0].sortOrder = Z;
}}
sortorder(A) ::= ASC. {A = eDb_SO_ASC;}
sortorder(A) ::= DESC. {A = eDb_SO_DESC;}
sortorder(A) ::= . {A = eDb_SO_ASC;}
///////////////////// The Expression Processing ////////////////////////////
//
%type expr {Expr *}
%destructor expr {eDbExprDelete($$);}
expr(A) ::= LP(B) expr(X) RP(E). {A = X;eDbExprSpan(A,&B,&E);}
expr(A) ::= nm(X) DOT nm(Y). {{
Expr *temp1 = eDbExpr(TK_ID,0,0,&X);
Expr *temp2 = eDbExpr(TK_ID,0,0,&Y);
A = eDbExpr(TK_DOT,temp1,temp2,0);
}
}
expr(A) ::= NULL(X). {A = eDbExpr(TK_NULL,0,0,&X);}
expr(A) ::= ID(X). {A = eDbExpr(TK_ID,0,0,&X);}
expr(A) ::= INTEGER(X). {A = eDbExpr(TK_INTEGER,0,0,&X);}
expr(A) ::= STRING(X). {A = eDbExpr(TK_STRING,0,0,&X);}
expr(A) ::= expr(X) AND expr(Y). {A = eDbExpr(TK_AND,X,Y,0);}
expr(A) ::= expr(X) OR expr(Y). {A = eDbExpr(TK_OR,X,Y,0);}
expr(A) ::= expr(X) LT expr(Y). {A = eDbExpr(TK_LT,X,Y,0);}
expr(A) ::= expr(X) GT expr(Y). {A = eDbExpr(TK_GT,X,Y,0);}
expr(A) ::= expr(X) LE expr(Y). {A = eDbExpr(TK_LE,X,Y,0);}
expr(A) ::= expr(X) GE expr(Y). {A = eDbExpr(TK_GE,X,Y,0);}
expr(A) ::= expr(X) NE expr(Y). {A = eDbExpr(TK_NE,X,Y,0);}
expr(A) ::= expr(X) EQ expr(Y). {A = eDbExpr(TK_EQ,X,Y,0);}
expr(A) ::= expr(X) LSHIFT expr(Y). {A = eDbExpr(TK_LSHIFT,X,Y,0);}
expr(A) ::= expr(X) RSHIFT expr(Y). {A = eDbExpr(TK_RSHIFT,X,Y,0);}
%type exprlist {ExprList *}
%destructor exprlist {eDbExprListDelete($$);}
exprlist(A) ::= exprlist(X) COMMA expr(Y). {A = eDbExprListAppend(X,Y,0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -