📄 edbpparse.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 eDbParser
%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 ::= cmdlist.
cmdlist ::= cmdlist ecmd.
cmdlist ::= 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,T,0);
}
create_table_args ::= LP columnlist RP(X). {
eDbEndTable(pParse,&X,0);
}
columnlist ::= columnlist COMMA column.
columnlist ::= column.
// About the only information used for a column is the name of the
// column. The type is always just "text". But the code will accept
// an elaborate typename. Perhaps someday we'll do something with it.
//
column ::= columnid type .
columnid ::= nm(X). {eDbAddColumn(pParse,&X);}
// Define operator precedence early so that this is the first occurance
// of the operator tokens in the grammer. Keeping the operators together
// causes them to be assigned integer values that are close together,
// which keeps parser tables smaller.
//
%left OR.
%left AND.
%right NOT.
%left EQ NE ISNULL NOTNULL IS LIKE GLOB BETWEEN IN.
%left GT GE LT LE.
%left BITAND BITOR LSHIFT RSHIFT.
%left PLUS MINUS.
%left STAR SLASH REM.
%left CONCAT.
%right UMINUS UPLUS BITNOT.
// And "ids" is an identifer-or-string.
//
%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 /////////////////////////////////////
//
cmd ::= DROP TABLE nm(X). {eDbDropTable(pParse,&X,0);}
//////////////////////// The SELECT statement /////////////////////////////////
//
cmd ::= select(X). {
eDbSelect(pParse, X, SRT_Callback, 0, 0, 0, 0);
eDbSelectDelete(X);
}
%type select {Select*}
%destructor select {eDbSelectDelete($$);}
%type oneselect {Select*}
%destructor oneselect {eDbSelectDelete($$);}
select(A) ::= oneselect(X). {A = X;}
oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
groupby_opt(P) having_opt(Q) orderby_opt(Z). {
A = eDbSelectNew(W,X,Y,P,Q,Z,D,L.limit,L.offset);
}
// The "distinct" nonterminal is true (1) if the DISTINCT keyword is
// present and false (0) if it is not.
//
%type distinct {int}
distinct(A) ::= DISTINCT. {A = 1;}
distinct(A) ::= ALL. {A = 0;}
distinct(A) ::= . {A = 0;}
// selcollist is a list of expressions that are to become the return
// values of the SELECT statement. The "*" in statements like
// "SELECT * FROM ..." is encoded as a special expression with an
// opcode of TK_ALL.
//
%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);
}
// An option "AS <id>" phrase that can follow one of the expressions that
// define the result set, or one of the tables in the FROM clause.
//
%type as {Token}
as(X) ::= AS nm(Y). { X = Y; }
as(X) ::= ids(Y). { X = Y; }
as(X) ::= . { X.n = 0; }
%type seltablist {SrcList*}
%destructor seltablist {eDbSrcListDelete($$);}
%type stl_prefix {SrcList*}
%destructor stl_prefix {eDbSrcListDelete($$);}
%type from {SrcList*}
%destructor from {eDbSrcListDelete($$);}
// A complete FROM clause.
//
from(A) ::= . {A = eDbMalloc(sizeof(*A));}
from(A) ::= FROM seltablist(X). {A = X;}
// "seltablist" is a "Select Table List" - the content of the FROM clause
// in a SELECT statement. "stl_prefix" is a prefix of this list.
//
seltablist(A) ::= nm(Y) dbnm(D) as(Z). {
A = eDbSrcListAppend(0,&Y,&D);
if( Z.n ) eDbSrcListAddAlias(A,&Z);
}
%type dbnm {Token}
dbnm(A) ::= . {A.z=0; A.n=0;}
dbnm(A) ::= DOT nm(X). {A = X;}
%type orderby_opt {ExprList*}
%destructor orderby_opt {eDbExprListDelete($$);}
%type sortlist {ExprList*}
%destructor sortlist {eDbExprListDelete($$);}
%type sortitem {Expr*}
%destructor sortitem {eDbExprDelete($$);}
orderby_opt(A) ::= . {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
sortlist(A) ::= sortlist(X) COMMA sortitem(Y)sortorder(Z). {
A = eDbExprListAppend(X,Y,0);
if( A ) A->a[A->nExpr-1].sortOrder = Z;
}
sortlist(A) ::= sortitem(Y) sortorder(Z). {
A = eDbExprListAppend(0,Y,0);
if( A ) A->a[0].sortOrder = Z;
}
sortitem(A) ::= expr(X). {A = X;}
%type sortorder {int}
%type collate {int}
sortorder(A) ::= ASC. {A = eDb_SO_ASC;}
sortorder(A) ::= DESC. {A = eDb_SO_DESC;}
sortorder(A) ::= . {A = eDb_SO_ASC;}
%type groupby_opt {ExprList*}
%destructor groupby_opt {eDbExprListDelete($$);}
groupby_opt(A) ::= . {A = 0;}
groupby_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;}
/////////////////////////// The DELETE statement /////////////////////////////
//
cmd ::= DELETE FROM nm(X) dbnm(D) where_opt(Y). {
eDbDeleteFrom(pParse, eDbSrcListAppend(0,&X,&D), Y);
}
%type where_opt {Expr*}
%destructor where_opt {eDbExprDelete($$);}
where_opt(A) ::= . {A = 0;}
where_opt(A) ::= WHERE expr(X). {A = X;}
%type setlist {ExprList*}
%destructor setlist {eDbExprListDelete($$);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -