scan.l
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:12k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. %{
  2. /*-------------------------------------------------------------------------
  3.  *
  4.  * scan.l
  5.  *   lexical scanner for POSTGRES
  6.  *
  7.  * Copyright (c) 1994, Regents of the University of California
  8.  *
  9.  *
  10.  * IDENTIFICATION
  11.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/parser/scan.l,v 1.50 1999/07/08 00:00:43 momjian Exp $
  12.  *
  13.  *-------------------------------------------------------------------------
  14.  */
  15. #include <ctype.h>
  16. #include <unistd.h>
  17. #ifndef __linux__
  18. #include <math.h>
  19. #else
  20. #include <stdlib.h>
  21. #endif /* __linux__ */
  22. #include <string.h>
  23. #include <errno.h>
  24. #include "postgres.h"
  25. #include "miscadmin.h"
  26. #include "nodes/pg_list.h"
  27. #include "nodes/parsenodes.h"
  28. #include "parser/gramparse.h"
  29. #include "parser/keywords.h"
  30. #include "parser/scansup.h"
  31. #include "parse.h"
  32. #include "utils/builtins.h"
  33. #ifdef  YY_READ_BUF_SIZE
  34. #undef  YY_READ_BUF_SIZE
  35. #endif
  36. #define YY_READ_BUF_SIZE MAX_PARSE_BUFFER
  37. #ifdef  YY_READ_BUF_SIZE
  38. #undef  YY_READ_BUF_SIZE
  39. #endif
  40. #define YY_READ_BUF_SIZE MAX_PARSE_BUFFER
  41. extern char *parseString;
  42. static char *parseCh;
  43. /* some versions of lex define this as a macro */
  44. #if defined(yywrap)
  45. #undef yywrap
  46. #endif /* yywrap */
  47. #if defined(FLEX_SCANNER)
  48. /* MAX_PARSE_BUFFER is defined in miscadmin.h */
  49. #define YYLMAX MAX_PARSE_BUFFER
  50. #define YY_NO_UNPUT
  51. static int myinput(char* buf, int max);
  52. #undef YY_INPUT
  53. #define YY_INPUT(buf,result,max) {result = myinput(buf,max);}
  54. #else
  55. #undef input
  56. int input();
  57. #undef unput
  58. void unput(char);
  59. #endif /* FLEX_SCANNER */
  60. extern YYSTYPE yylval;
  61. int llen;
  62. char literal[MAX_PARSE_BUFFER];
  63. %}
  64. /* OK, here is a short description of lex/flex rules behavior.
  65.  * The longest pattern which matches an input string is always chosen.
  66.  * For equal-length patterns, the first occurring in the rules list is chosen.
  67.  * INITIAL is the starting condition, to which all non-conditional rules apply.
  68.  * When in an exclusive condition, only those rules defined for that condition apply.
  69.  *
  70.  * Exclusive states change parsing rules while the state is active.
  71.  * There are exclusive states for quoted strings, extended comments,
  72.  *  and to eliminate parsing troubles for numeric strings.
  73.  * Exclusive states:
  74.  *  <xb> binary numeric string - thomas 1997-11-16
  75.  *  <xc> extended C-style comments - tgl 1997-07-12
  76.  *  <xd> delimited identifiers (double-quoted identifiers) - tgl 1997-10-27
  77.  *  <xh> hexadecimal numeric string - thomas 1997-11-16
  78.  *  <xm> numeric strings with embedded minus sign - tgl 1997-09-05
  79.  *  <xq> quoted strings - tgl 1997-07-30
  80.  *
  81.  * The "extended comment" syntax closely resembles allowable operator syntax.
  82.  * So, when in condition <xc>, only strings which would terminate the
  83.  *  "extended comment" trigger any action other than "ignore".
  84.  * Be sure to match _any_ candidate comment, including those with appended
  85.  * operator-like symbols. - thomas 1997-07-14
  86.  */
  87. %x xb
  88. %x xc
  89. %x xd
  90. %x xh
  91. %x xm
  92. %x xq
  93. /* Binary number
  94.  */
  95. xbstart [bB]{quote}
  96. xbstop {quote}
  97. xbinside [^']*
  98. xbcat {quote}{space}*n{space}*{quote}
  99. /* Hexadecimal number
  100.  */
  101. xhstart [xX]{quote}
  102. xhstop {quote}
  103. xhinside [^']*
  104. xhcat {quote}{space}*n{space}*{quote}
  105. /* Extended quote
  106.  * xqdouble implements SQL92 embedded quote
  107.  * xqcat allows strings to cross input lines
  108.  * Note: reduction of '' and  sequences to output text is done in scanstr(),
  109.  * not by rules here.
  110.  */
  111. quote '
  112. xqstart {quote}
  113. xqstop {quote}
  114. xqdouble {quote}{quote}
  115. xqinside [^\']*
  116. xqliteral [\](.|n)
  117. xqcat {quote}{space}*n{space}*{quote}
  118. /* Delimited quote
  119.  * Allows embedded spaces and other special characters into identifiers.
  120.  */
  121. dquote "
  122. xdstart {dquote}
  123. xdstop {dquote}
  124. xdinside [^"]*
  125. /* Comments
  126.  * Ignored by the scanner and parser.
  127.  */
  128. xcline [/][*].*[*][/]{space}*n*
  129. xcstart [/][*]{op_and_self}*
  130. xcstop {op_and_self}*[*][/]({space}*|n)
  131. xcinside [^*]*
  132. xcstar [^/]
  133. digit [0-9]
  134. number [-+.0-9Ee]
  135. letter [200-377_A-Za-z]
  136. letter_or_digit [200-377_A-Za-z0-9]
  137. identifier {letter}{letter_or_digit}*
  138. typecast "::"
  139. self [,()[].;$:+-*/%^<>=|]
  140. op_and_self [~!@#^&|`?$:+-*/%<>=]
  141. operator {op_and_self}+
  142. xmstop -
  143. integer [-]?{digit}+
  144. decimal [-]?(({digit}*.{digit}+)|({digit}+.{digit}*))
  145. real [-]?((({digit}*.{digit}+)|({digit}+.{digit}*)|({digit}+))([Ee][-+]?{digit}+))
  146. /*
  147. real [-]?(((({digit}*.{digit}+)|({digit}+.{digit}*))([Ee][-+]?{digit}+)?)|({digit}+[Ee][-+]?{digit}+))
  148. */
  149. param ${integer}
  150. comment ("--"|"//").*n
  151. space [ tnf]
  152. other .
  153. /* DO NOT PUT ANY COMMENTS IN THE FOLLOWING SECTION.
  154.  * AT&T lex does not properly handle C-style comments in this second lex block.
  155.  * So, put comments here. tgl - 1997-09-08
  156.  *
  157.  * Quoted strings must allow some special characters such as single-quote
  158.  *  and newline.
  159.  * Embedded single-quotes are implemented both in the SQL/92-standard
  160.  *  style of two adjacent single quotes "''" and in the Postgres/Java style
  161.  *  of escaped-quote "'".
  162.  * Other embedded escaped characters are matched explicitly and the leading
  163.  *  backslash is dropped from the string. - thomas 1997-09-24
  164.  */
  165. %%
  166. {comment} { /* ignore */ }
  167. {xcline} { /* ignore */ }
  168. <xc>{xcstar} |
  169. {xcstart} { BEGIN(xc); }
  170. <xc>{xcstop} { BEGIN(INITIAL); }
  171. <xc>{xcinside} { /* ignore */ }
  172. {xbstart} {
  173. BEGIN(xb);
  174. llen = 0;
  175. *literal = '';
  176. }
  177. <xb>{xbstop} {
  178. char* endptr;
  179. BEGIN(INITIAL);
  180. errno = 0;
  181. yylval.ival = strtol((char *)literal,&endptr,2);
  182. if (*endptr != '' || errno == ERANGE)
  183. elog(ERROR,"Bad binary integer input '%s'",literal);
  184. return ICONST;
  185. }
  186. <xh>{xhinside} |
  187. <xb>{xbinside} {
  188. if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
  189. elog(ERROR,"quoted string parse buffer of %d chars exceeded",MAX_PARSE_BUFFER);
  190. memcpy(literal+llen, yytext, yyleng+1);
  191. llen += yyleng;
  192. }
  193. <xh>{xhcat} |
  194. <xb>{xbcat} {
  195. }
  196. {xhstart} {
  197. BEGIN(xh);
  198. llen = 0;
  199. *literal = '';
  200. }
  201. <xh>{xhstop} {
  202. char* endptr;
  203. BEGIN(INITIAL);
  204. errno = 0;
  205. yylval.ival = strtol((char *)literal,&endptr,16);
  206. if (*endptr != '' || errno == ERANGE)
  207. elog(ERROR,"Bad hexadecimal integer input '%s'",literal);
  208. return ICONST;
  209. }
  210. {xqstart} {
  211. BEGIN(xq);
  212. llen = 0;
  213. *literal = '';
  214. }
  215. <xq>{xqstop} {
  216. BEGIN(INITIAL);
  217. yylval.str = pstrdup(scanstr(literal));
  218. return SCONST;
  219. }
  220. <xq>{xqdouble} |
  221. <xq>{xqinside} |
  222. <xq>{xqliteral} {
  223. if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
  224. elog(ERROR,"quoted string parse buffer of %d chars exceeded",MAX_PARSE_BUFFER);
  225. memcpy(literal+llen, yytext, yyleng+1);
  226. llen += yyleng;
  227. }
  228. <xq>{xqcat} {
  229. }
  230. {xdstart} {
  231. BEGIN(xd);
  232. llen = 0;
  233. *literal = '';
  234. }
  235. <xd>{xdstop} {
  236. BEGIN(INITIAL);
  237. yylval.str = pstrdup(literal);
  238. return IDENT;
  239. }
  240. <xd>{xdinside} {
  241. if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
  242. elog(ERROR,"quoted string parse buffer of %d chars exceeded",MAX_PARSE_BUFFER);
  243. memcpy(literal+llen, yytext, yyleng+1);
  244. llen += yyleng;
  245. }
  246. <xm>{space}* { /* ignore */ }
  247. <xm>{xmstop} {
  248. BEGIN(INITIAL);
  249. return yytext[0];
  250. }
  251. {typecast} { return TYPECAST; }
  252. {self}/{space}*-[.0-9] {
  253. BEGIN(xm);
  254. return yytext[0];
  255. }
  256. {self} {  return yytext[0]; }
  257. {self} {  return yytext[0]; }
  258. {operator}/-[.0-9] {
  259. yylval.str = pstrdup((char*)yytext);
  260. return Op;
  261. }
  262. {operator} {
  263. if (strcmp((char*)yytext,"!=") == 0)
  264. yylval.str = pstrdup("<>"); /* compatability */
  265. else
  266. yylval.str = pstrdup((char*)yytext);
  267. return Op;
  268. }
  269. {param} {
  270. yylval.ival = atoi((char*)&yytext[1]);
  271. return PARAM;
  272. }
  273. {identifier}/{space}*-{number} {
  274. int i;
  275. ScanKeyword *keyword;
  276. BEGIN(xm);
  277. for(i = 0; yytext[i]; i++)
  278. if (isascii((unsigned char)yytext[i]) &&
  279. isupper(yytext[i]))
  280. yytext[i] = tolower(yytext[i]);
  281. if (i >= NAMEDATALEN)
  282. yytext[NAMEDATALEN-1] = '';
  283. keyword = ScanKeywordLookup((char*)yytext);
  284. if (keyword != NULL) {
  285. return keyword->value;
  286. }
  287. else
  288. {
  289. yylval.str = pstrdup((char*)yytext);
  290. return IDENT;
  291. }
  292. }
  293. {integer}/{space}*-{number} {
  294. char* endptr;
  295. BEGIN(xm);
  296. errno = 0;
  297. yylval.ival = strtol((char *)yytext,&endptr,10);
  298. if (*endptr != '' || errno == ERANGE)
  299. {
  300. errno = 0;
  301. #if 0
  302. yylval.dval = strtod(((char *)yytext),&endptr);
  303. if (*endptr != '' || errno == ERANGE)
  304. elog(ERROR,"Bad integer input '%s'",yytext);
  305. CheckFloat8Val(yylval.dval);
  306. elog(NOTICE,"Integer input '%s' is out of range; promoted to float", yytext);
  307. return FCONST;
  308. #endif
  309. yylval.str = pstrdup((char*)yytext);
  310. return SCONST;
  311. }
  312. return ICONST;
  313. }
  314. {decimal}/{space}*-{number} {
  315. char* endptr;
  316. BEGIN(xm);
  317. if (strlen((char *)yytext) <= 17)
  318. {
  319. errno = 0;
  320. yylval.dval = strtod(((char *)yytext),&endptr);
  321. if (*endptr != '' || errno == ERANGE)
  322. elog(ERROR,"Bad float8 input '%s'",yytext);
  323. CheckFloat8Val(yylval.dval);
  324. return FCONST;
  325. }
  326. yylval.str = pstrdup((char*)yytext);
  327. return SCONST;
  328. }
  329. {real}/{space}*-{number} {
  330. char* endptr;
  331. BEGIN(xm);
  332. errno = 0;
  333. yylval.dval = strtod(((char *)yytext),&endptr);
  334. if (*endptr != '' || errno == ERANGE)
  335. elog(ERROR,"Bad float8 input '%s'",yytext);
  336. CheckFloat8Val(yylval.dval);
  337. return FCONST;
  338. }
  339. {integer} {
  340. char* endptr;
  341. errno = 0;
  342. yylval.ival = strtol((char *)yytext,&endptr,10);
  343. if (*endptr != '' || errno == ERANGE)
  344. {
  345. errno = 0;
  346. #if 0
  347. yylval.dval = strtod(((char *)yytext),&endptr);
  348. if (*endptr != '' || errno == ERANGE)
  349. elog(ERROR,"Bad integer input '%s'",yytext);
  350. CheckFloat8Val(yylval.dval);
  351. elog(NOTICE,"Integer input '%s' is out of range; promoted to float", yytext);
  352. return FCONST;
  353. #endif
  354. yylval.str = pstrdup((char*)yytext);
  355. return SCONST;
  356. }
  357. return ICONST;
  358. }
  359. {decimal} {
  360. char* endptr;
  361. if (strlen((char *)yytext) <= 17)
  362. {
  363. errno = 0;
  364. yylval.dval = strtod((char *)yytext,&endptr);
  365. if (*endptr != '' || errno == ERANGE)
  366. elog(ERROR,"Bad float input '%s'",yytext);
  367. CheckFloat8Val(yylval.dval);
  368. return FCONST;
  369. }
  370. yylval.str = pstrdup((char*)yytext);
  371. return SCONST;
  372. }
  373. {real} {
  374. char* endptr;
  375. errno = 0;
  376. yylval.dval = strtod((char *)yytext,&endptr);
  377. if (*endptr != '' || errno == ERANGE)
  378. elog(ERROR,"Bad float input '%s'",yytext);
  379. CheckFloat8Val(yylval.dval);
  380. return FCONST;
  381. }
  382. {identifier} {
  383. int i;
  384. ScanKeyword *keyword;
  385. for(i = 0; yytext[i]; i++)
  386. if (isascii((unsigned char)yytext[i]) &&
  387. isupper(yytext[i]))
  388. yytext[i] = tolower(yytext[i]);
  389. if (i >= NAMEDATALEN)
  390. yytext[NAMEDATALEN-1] = '';
  391. keyword = ScanKeywordLookup((char*)yytext);
  392. if (keyword != NULL) {
  393. return keyword->value;
  394. }
  395. else
  396. {
  397. yylval.str = pstrdup((char*)yytext);
  398. return IDENT;
  399. }
  400. }
  401. {space} { /* ignore */ }
  402. {other} { return yytext[0]; }
  403. %%
  404. void yyerror(char message[])
  405. {
  406. elog(ERROR, "parser: %s at or near "%s"", message, yytext);
  407. }
  408. int yywrap()
  409. {
  410. return(1);
  411. }
  412. /*
  413.  init_io:
  414. called by postgres before any actual parsing is done
  415. */
  416. void
  417. init_io()
  418. {
  419. /* it's important to set this to NULL
  420.    because input()/myinput() checks the non-nullness of parseCh
  421.    to know when to pass the string to lex/flex */
  422. parseCh = NULL;
  423. #if defined(FLEX_SCANNER)
  424. if (YY_CURRENT_BUFFER)
  425. yy_flush_buffer(YY_CURRENT_BUFFER);
  426. #endif /* FLEX_SCANNER */
  427. BEGIN INITIAL;
  428. }
  429. #if !defined(FLEX_SCANNER)
  430. /* get lex input from a string instead of from stdin */
  431. int
  432. input()
  433. {
  434. if (parseCh == NULL)
  435. {
  436. parseCh = parseString;
  437. return(*parseCh++);
  438. }
  439. else if (*parseCh == '')
  440. return(0);
  441. else
  442. return(*parseCh++);
  443. }
  444. /* undo lex input from a string instead of from stdin */
  445. void
  446. unput(char c)
  447. {
  448. if (parseCh == NULL)
  449. elog(FATAL, "Unput() failed.n");
  450. else if (c != 0)
  451. *--parseCh = c;
  452. }
  453. #endif /* !defined(FLEX_SCANNER) */
  454. #ifdef FLEX_SCANNER
  455. /* input routine for flex to read input from a string instead of a file */
  456. static int
  457. myinput(char* buf, int max)
  458. {
  459. int len, copylen;
  460. if (parseCh == NULL)
  461. {
  462. len = strlen(parseString);
  463. if (len >= max)
  464. copylen = max - 1;
  465. else
  466. copylen = len;
  467. if (copylen > 0)
  468. memcpy(buf, parseString, copylen);
  469. buf[copylen] = '';
  470. parseCh = parseString;
  471. return copylen;
  472. }
  473. else
  474. return 0; /* end of string */
  475. }
  476. #endif /* FLEX_SCANNER */