PostgreSQL中的Rules有什么作用
本篇内容介绍了“PostgreSQL中的Rules有什么作用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
Flex输入文件由四部分组成:
%{Declarations%}Definitions%%Rules%%UsersubroutinesRules
在Flex的模式文件中,%%和%%之间的内容被称为规则(rules),每一行表示一条规则,每条规则由匹配模式(pattern)和 动作(action)组成。其中模式在前面,用正则表达式表示,动作在后面,即C代码。每当一个模式被匹配到时,后面的C代码将被执行。
Flex会将规则翻译成名为yylex的函数,该函数扫描输入文件(默认标准输入),当扫描到一个完整的、最长的、可以和某条规则的正则表达式所匹配的输入时,函数会执行此规则后面的C代码。如果代码中没有return语句,则执行完毕后,yylex会继续运行,开始下一轮的扫描和匹配。注意:当有多条规则的模式被匹配到时, yylex会优先选择匹配长度最长的那条规则,如果有匹配长度相等的规则,则选择排在最前面的那条规则。
PG中的规则定义如下:
%%{whitespace}{//---------空白字符//忽略,不作任何处理/*ignore*/}{xcstart}{//---------C风格注释/*Setlocationincaseofsyntaxerrorincomment*///设置位置,以防注释中的语法错误SET_YYLLOC();//深度yyextra->xcdepth=0;//进入xc状态BEGIN(xc);/*Putbackanycharacterspastslash-star;seeabove*///把斜杠星后的字符放回去//注意:"/*"是2个字符,从位置2(偏移从0起算)开始把之后的字符放回去yyless(2);}<xc>{xcstart}{//遇到下一层的注释,深度+1(yyextra->xcdepth)++;/*Putbackanycharacterspastslash-star;seeabove*///类似的,把之后的字符放回去yyless(2);}<xc>{xcstop}{//层次≤0,回到INITIAL状态,否则层次减1if(yyextra->xcdepth<=0)BEGIN(INITIAL);else(yyextra->xcdepth)--;}<xc>{xcinside}{//注释里面的内容,忽略/*ignore*/}<xc>{op_chars}{//注释里面的内容,忽略/*ignore*/}<xc>\*+{//注释里面的内容,忽略/*ignore*/}<xc><<EOF>>{yyerror("unterminated/*comment");}//遇到结束符,出错{xbstart}{/*Binarybittype.*Atsomepointweshouldsimplypassthestring*forwardtotheparserandlabelitthere.*Inthemeantime,placealeading"b"onthestring*tomarkitfortheinputroutineasabinarystring.*///---------二进制位串//在某些点上,我们应该简单的把字符串向前传递给解析器并标记它//在此期间,设置一个打头的字符"b"以标记该输入为二进制串SET_YYLLOC();BEGIN(xb);startlit();addlitchar('b',yyscanner);}<xb>{quotestop}|<xb>{quotefail}{yyless(1);BEGIN(INITIAL);yylval->str=litbufdup(yyscanner);returnBCONST;}<xh>{xhinside}|<xb>{xbinside}{addlit(yytext,yyleng,yyscanner);}<xh>{quotecontinue}|<xb>{quotecontinue}{/*ignore*/}<xb><<EOF>>{yyerror("unterminatedbitstringliteral");}{xhstart}{//-------------十六进制串/*Hexadecimalbittype.*Atsomepointweshouldsimplypassthestring*forwardtotheparserandlabelitthere.*Inthemeantime,placealeading"x"onthestring*tomarkitfortheinputroutineasahexstring.*/SET_YYLLOC();BEGIN(xh);startlit();addlitchar('x',yyscanner);}<xh>{quotestop}|<xh>{quotefail}{yyless(1);BEGIN(INITIAL);yylval->str=litbufdup(yyscanner);returnXCONST;}<xh><<EOF>>{yyerror("unterminatedhexadecimalstringliteral");}{xnstart}{//-------------国家字符/*Nationalcharacter.*Wewillpassthisalongasanormalcharacterstring,*butprecededwithaninternally-generated"NCHAR".*/constScanKeyword*keyword;SET_YYLLOC();yyless(1);/*eatonly'n'thistime*/keyword=ScanKeywordLookup("nchar",yyextra->keywords,yyextra->num_keywords);if(keyword!=NULL){yylval->keyword=keyword->name;returnkeyword->value;}else{/*IfNCHARisn'takeyword,justreturn"n"*/yylval->str=pstrdup("n");returnIDENT;}}{xqstart}{yyextra->warn_on_first_escape=true;yyextra->saw_non_ascii=false;SET_YYLLOC();if(yyextra->standard_conforming_strings)BEGIN(xq);elseBEGIN(xe);startlit();}{xestart}{yyextra->warn_on_first_escape=false;yyextra->saw_non_ascii=false;SET_YYLLOC();BEGIN(xe);startlit();}{xusstart}{SET_YYLLOC();if(!yyextra->standard_conforming_strings)ereport(ERROR,(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),errmsg("unsafeuseofstringconstantwithUnicodeescapes"),errdetail("StringconstantswithUnicodeescapescannotbeusedwhenstandard_conforming_stringsisoff."),lexer_errposition()));BEGIN(xus);startlit();}<xq,xe>{quotestop}|<xq,xe>{quotefail}{yyless(1);BEGIN(INITIAL);/**checkthatthedataremainsvalidifitmighthavebeen*madeinvalidbyunescapinganychars.*/if(yyextra->saw_non_ascii)pg_verifymbstr(yyextra->literalbuf,yyextra->literallen,false);yylval->str=litbufdup(yyscanner);returnSCONST;}<xus>{quotestop}|<xus>{quotefail}{/*throwbackallbutthequote*/yyless(1);/*xusendstatelooksforpossibleUESCAPE*/BEGIN(xusend);}<xusend>{whitespace}{/*stayinxusendstateoverwhitespace*/}<xusend><<EOF>>|<xusend>{other}|<xusend>{xustop1}{/*noUESCAPEafterthequote,throwbackeverything*/yyless(0);BEGIN(INITIAL);yylval->str=litbuf_udeescape('\\',yyscanner);returnSCONST;}<xusend>{xustop2}{/*foundUESCAPEaftertheendquote*/BEGIN(INITIAL);if(!check_uescapechar(yytext[yyleng-2])){SET_YYLLOC();ADVANCE_YYLLOC(yyleng-2);yyerror("invalidUnicodeescapecharacter");}yylval->str=litbuf_udeescape(yytext[yyleng-2],yyscanner);returnSCONST;}<xq,xe,xus>{xqdouble}{addlitchar('\'',yyscanner);}<xq,xus>{xqinside}{addlit(yytext,yyleng,yyscanner);}<xe>{xeinside}{addlit(yytext,yyleng,yyscanner);}<xe>{xeunicode}{pg_wcharc=strtoul(yytext+2,NULL,16);check_escape_warning(yyscanner);if(is_utf16_surrogate_first(c)){yyextra->utf16_first_part=c;BEGIN(xeu);}elseif(is_utf16_surrogate_second(c))yyerror("invalidUnicodesurrogatepair");elseaddunicode(c,yyscanner);}<xeu>{xeunicode}{pg_wcharc=strtoul(yytext+2,NULL,16);if(!is_utf16_surrogate_second(c))yyerror("invalidUnicodesurrogatepair");c=surrogate_pair_to_codepoint(yyextra->utf16_first_part,c);addunicode(c,yyscanner);BEGIN(xe);}<xeu>.{yyerror("invalidUnicodesurrogatepair");}<xeu>\n{yyerror("invalidUnicodesurrogatepair");}<xeu><<EOF>>{yyerror("invalidUnicodesurrogatepair");}<xe,xeu>{xeunicodefail}{ereport(ERROR,(errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),errmsg("invalidUnicodeescape"),errhint("Unicodeescapesmustbe\\uXXXXor\\UXXXXXXXX."),lexer_errposition()));}<xe>{xeescape}{if(yytext[1]=='\''){if(yyextra->backslash_quote==BACKSLASH_QUOTE_OFF||(yyextra->backslash_quote==BACKSLASH_QUOTE_SAFE_ENCODING&&PG_ENCODING_IS_CLIENT_ONLY(pg_get_client_encoding())))ereport(ERROR,(errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),errmsg("unsafeuseof\\'inastringliteral"),errhint("Use''towritequotesinstrings.\\'isinsecureinclient-onlyencodings."),lexer_errposition()));}check_string_escape_warning(yytext[1],yyscanner);addlitchar(unescape_single_char(yytext[1],yyscanner),yyscanner);}<xe>{xeoctesc}{unsignedcharc=strtoul(yytext+1,NULL,8);check_escape_warning(yyscanner);addlitchar(c,yyscanner);if(c=='\0'||IS_HIGHBIT_SET(c))yyextra->saw_non_ascii=true;}<xe>{xehexesc}{unsignedcharc=strtoul(yytext+2,NULL,16);check_escape_warning(yyscanner);addlitchar(c,yyscanner);if(c=='\0'||IS_HIGHBIT_SET(c))yyextra->saw_non_ascii=true;}<xq,xe,xus>{quotecontinue}{/*ignore*/}<xe>.{/*Thisisonlyneededfor\justbeforeEOF*/addlitchar(yytext[0],yyscanner);}<xq,xe,xus><<EOF>>{yyerror("unterminatedquotedstring");}{dolqdelim}{SET_YYLLOC();yyextra->dolqstart=pstrdup(yytext);BEGIN(xdolq);startlit();}{dolqfailed}{SET_YYLLOC();/*throwbackallbuttheinitial"$"*/yyless(1);/*andtreatitas{other}*/returnyytext[0];}<xdolq>{dolqdelim}{if(strcmp(yytext,yyextra->dolqstart)==0){pfree(yyextra->dolqstart);yyextra->dolqstart=NULL;BEGIN(INITIAL);yylval->str=litbufdup(yyscanner);returnSCONST;}else{/**Whenwefailtomatch$...$todolqstart,transfer*the$...parttotheoutput,butputbackthefinal*$forrescanning.Consider$delim$...$junk$delim$*/addlit(yytext,yyleng-1,yyscanner);yyless(yyleng-1);}}<xdolq>{dolqinside}{addlit(yytext,yyleng,yyscanner);}<xdolq>{dolqfailed}{addlit(yytext,yyleng,yyscanner);}<xdolq>.{/*Thisisonlyneededfor$insidethequotedtext*/addlitchar(yytext[0],yyscanner);}<xdolq><<EOF>>{yyerror("unterminateddollar-quotedstring");}{xdstart}{SET_YYLLOC();BEGIN(xd);startlit();}{xuistart}{SET_YYLLOC();BEGIN(xui);startlit();}<xd>{xdstop}{char*ident;BEGIN(INITIAL);if(yyextra->literallen==0)yyerror("zero-lengthdelimitedidentifier");ident=litbufdup(yyscanner);if(yyextra->literallen>=NAMEDATALEN)truncate_identifier(ident,yyextra->literallen,true);yylval->str=ident;returnIDENT;}<xui>{dquote}{yyless(1);/*xuiendstatelooksforpossibleUESCAPE*/BEGIN(xuiend);}<xuiend>{whitespace}{/*stayinxuiendstateoverwhitespace*/}<xuiend><<EOF>>|<xuiend>{other}|<xuiend>{xustop1}{/*noUESCAPEafterthequote,throwbackeverything*/char*ident;intidentlen;yyless(0);BEGIN(INITIAL);if(yyextra->literallen==0)yyerror("zero-lengthdelimitedidentifier");ident=litbuf_udeescape('\\',yyscanner);identlen=strlen(ident);if(identlen>=NAMEDATALEN)truncate_identifier(ident,identlen,true);yylval->str=ident;returnIDENT;}<xuiend>{xustop2}{/*foundUESCAPEaftertheendquote*/char*ident;intidentlen;BEGIN(INITIAL);if(yyextra->literallen==0)yyerror("zero-lengthdelimitedidentifier");if(!check_uescapechar(yytext[yyleng-2])){SET_YYLLOC();ADVANCE_YYLLOC(yyleng-2);yyerror("invalidUnicodeescapecharacter");}ident=litbuf_udeescape(yytext[yyleng-2],yyscanner);identlen=strlen(ident);if(identlen>=NAMEDATALEN)truncate_identifier(ident,identlen,true);yylval->str=ident;returnIDENT;}<xd,xui>{xddouble}{addlitchar('"',yyscanner);}<xd,xui>{xdinside}{addlit(yytext,yyleng,yyscanner);}<xd,xui><<EOF>>{yyerror("unterminatedquotedidentifier");}{xufailed}{char*ident;SET_YYLLOC();/*throwbackallbuttheinitialu/U*/yyless(1);/*andtreatitas{identifier}*/ident=downcase_truncate_identifier(yytext,yyleng,true);yylval->str=ident;returnIDENT;}{typecast}{SET_YYLLOC();returnTYPECAST;}{dot_dot}{SET_YYLLOC();returnDOT_DOT;}{colon_equals}{SET_YYLLOC();returnCOLON_EQUALS;}{equals_greater}{SET_YYLLOC();returnEQUALS_GREATER;}{less_equals}{SET_YYLLOC();returnLESS_EQUALS;}{greater_equals}{SET_YYLLOC();returnGREATER_EQUALS;}{less_greater}{/*Weacceptboth"<>"and"!="asmeaningNOT_EQUALS*/SET_YYLLOC();returnNOT_EQUALS;}{not_equals}{/*Weacceptboth"<>"and"!="asmeaningNOT_EQUALS*/SET_YYLLOC();returnNOT_EQUALS;}{self}{SET_YYLLOC();returnyytext[0];}{operator}{/**Checkforembeddedslash-starordash-dash;those*arecommentstarts,sooperatormuststopthere.*Notethatslash-starordash-dashatthefirst*characterwillmatchapriorrule,notthisone.*/intnchars=yyleng;char*slashstar=strstr(yytext,"/*");char*dashdash=strstr(yytext,"--");if(slashstar&&dashdash){/*ifbothappear,takethefirstone*/if(slashstar>dashdash)slashstar=dashdash;}elseif(!slashstar)slashstar=dashdash;if(slashstar)nchars=slashstar-yytext;/**ForSQLcompatibility,'+'and'-'cannotbethe*lastcharofamulti-charoperatorunlesstheoperator*containscharsthatarenotinSQLoperators.*Theideaistolex'=-'astwooperators,butnot*toforbidoperatornameslike'?-'thatcouldnotbe*sequencesofSQLoperators.*/if(nchars>1&&(yytext[nchars-1]=='+'||yytext[nchars-1]=='-')){intic;for(ic=nchars-2;ic>=0;ic--){charc=yytext[ic];if(c=='~'||c=='!'||c=='@'||c=='#'||c=='^'||c=='&'||c=='|'||c=='`'||c=='?'||c=='%')break;}if(ic<0){/**didn'tfindaqualifyingcharacter,soremove*alltrailing[+-]*/do{nchars--;}while(nchars>1&&(yytext[nchars-1]=='+'||yytext[nchars-1]=='-'));}}SET_YYLLOC();if(nchars<yyleng){/*Striptheunwantedcharsfromthetoken*/yyless(nchars);/**Ifwhatwehaveleftisonlyonechar,andit's*oneofthecharactersmatching"self",then*returnitasacharactertokenthesameway*thatthe"self"rulewouldhave.*/if(nchars==1&&strchr(",()[].;:+-*/%^<>=",yytext[0]))returnyytext[0];/**Likewise,ifwhatwehaveleftistwochars,and*thosematchthetokens">=","<=","=>","<>"or*"!=",thenwemustreturntheappropriatetoken*ratherthanthegenericOp.*/if(nchars==2){if(yytext[0]=='='&&yytext[1]=='>')returnEQUALS_GREATER;if(yytext[0]=='>'&&yytext[1]=='=')returnGREATER_EQUALS;if(yytext[0]=='<'&&yytext[1]=='=')returnLESS_EQUALS;if(yytext[0]=='<'&&yytext[1]=='>')returnNOT_EQUALS;if(yytext[0]=='!'&&yytext[1]=='=')returnNOT_EQUALS;}}/**Complainifoperatoristoolong.Unlikethecase*foridentifiers,wemakethisanerrornotanotice-*and-truncate,becausetheoddsarewearelookingat*asyntacticmistakeanyway.*/if(nchars>=NAMEDATALEN)yyerror("operatortoolong");yylval->str=pstrdup(yytext);returnOp;}{param}{SET_YYLLOC();yylval->ival=atol(yytext+1);returnPARAM;}{integer}{SET_YYLLOC();returnprocess_integer_literal(yytext,yylval);}{decimal}{SET_YYLLOC();yylval->str=pstrdup(yytext);returnFCONST;}{decimalfail}{/*throwbackthe..,andtreatasinteger*/yyless(yyleng-2);SET_YYLLOC();returnprocess_integer_literal(yytext,yylval);}{real}{SET_YYLLOC();yylval->str=pstrdup(yytext);returnFCONST;}{realfail1}{/**throwbackthe[Ee],andtreatas{decimal}.Note*thatitispossibletheinputisactually{integer},*butsincethiscasewillalmostcertainlyleadtoa*syntaxerroranyway,wedon'tbothertodistinguish.*/yyless(yyleng-1);SET_YYLLOC();yylval->str=pstrdup(yytext);returnFCONST;}{realfail2}{/*throwbackthe[Ee][+-],andproceedasabove*/yyless(yyleng-2);SET_YYLLOC();yylval->str=pstrdup(yytext);returnFCONST;}{identifier}{//----------标识符constScanKeyword*keyword;char*ident;SET_YYLLOC();/*Isitakeyword?*///是否关键字?keyword=ScanKeywordLookup(yytext,yyextra->keywords,yyextra->num_keywords);if(keyword!=NULL){//是,则返回关键字值yylval->keyword=keyword->name;returnkeyword->value;}/**No.Converttheidentifiertolowercase,andtruncate*ifnecessary.*///如果不是关键字,则设置为小写字母,如需要则截断ident=downcase_truncate_identifier(yytext,yyleng,true);yylval->str=ident;returnIDENT;}{other}{SET_YYLLOC();returnyytext[0];}<<EOF>>{SET_YYLLOC();yyterminate();}%%
“PostgreSQL中的Rules有什么作用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。