Line data Source code
1 : %top{ 2 : /* 3 : * A scanner for EMP-style numeric ranges 4 : * contrib/cube/cubescan.l 5 : */ 6 : 7 : #include "postgres.h" 8 : 9 : /* 10 : * NB: include cubeparse.h only AFTER defining YYSTYPE (to match cubeparse.y) 11 : * and cubedata.h for NDBOX. 12 : */ 13 : #include "cubedata.h" 14 : #define YYSTYPE char * 15 : #include "cubeparse.h" 16 : } 17 : 18 : %{ 19 : /* LCOV_EXCL_START */ 20 : 21 : /* No reason to constrain amount of data slurped */ 22 : #define YY_READ_BUF_SIZE 16777216 23 : 24 : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */ 25 : #undef fprintf 26 : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg) 27 : 28 : static void 29 : fprintf_to_ereport(const char *fmt, const char *msg) 30 : { 31 : ereport(ERROR, (errmsg_internal("%s", msg))); 32 : } 33 : 34 : /* Handles to the buffer that the lexer uses internally */ 35 : static YY_BUFFER_STATE scanbufhandle; 36 : static char *scanbuf; 37 : %} 38 : 39 : %option 8bit 40 : %option never-interactive 41 : %option nodefault 42 : %option noinput 43 : %option nounput 44 : %option noyywrap 45 : %option warn 46 : %option prefix="cube_yy" 47 : 48 : 49 : n [0-9]+ 50 : integer [+-]?{n} 51 : real [+-]?({n}\.{n}?|\.{n}) 52 : float ({integer}|{real})([eE]{integer})? 53 : infinity [+-]?[iI][nN][fF]([iI][nN][iI][tT][yY])? 54 : NaN [nN][aA][nN] 55 : 56 : %% 57 : 58 : {float} cube_yylval = yytext; return CUBEFLOAT; 59 : {infinity} cube_yylval = yytext; return CUBEFLOAT; 60 : {NaN} cube_yylval = yytext; return CUBEFLOAT; 61 : \[ cube_yylval = "("; return O_BRACKET; 62 : \] cube_yylval = ")"; return C_BRACKET; 63 : \( cube_yylval = "("; return O_PAREN; 64 : \) cube_yylval = ")"; return C_PAREN; 65 : \, cube_yylval = ","; return COMMA; 66 : [ \t\n\r\f\v]+ /* discard spaces */ 67 : . return yytext[0]; /* alert parser of the garbage */ 68 : 69 : %% 70 : 71 : /* LCOV_EXCL_STOP */ 72 : 73 : /* result and scanbuflen are not used, but Bison expects this signature */ 74 : void 75 48 : cube_yyerror(NDBOX **result, Size scanbuflen, 76 : struct Node *escontext, 77 : const char *message) 78 : { 79 48 : if (*yytext == YY_END_OF_BUFFER_CHAR) 80 : { 81 6 : errsave(escontext, 82 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 83 : errmsg("invalid input syntax for cube"), 84 : /* translator: %s is typically "syntax error" */ 85 : errdetail("%s at end of input", message))); 86 : } 87 : else 88 : { 89 42 : errsave(escontext, 90 : (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 91 : errmsg("invalid input syntax for cube"), 92 : /* translator: first %s is typically "syntax error" */ 93 : errdetail("%s at or near \"%s\"", message, yytext))); 94 : } 95 2 : } 96 : 97 : 98 : /* 99 : * Called before any actual parsing is done 100 : */ 101 : void 102 6870 : cube_scanner_init(const char *str, Size *scanbuflen) 103 : { 104 6870 : Size slen = strlen(str); 105 : 106 : /* 107 : * Might be left over after ereport() 108 : */ 109 6870 : if (YY_CURRENT_BUFFER) 110 60 : yy_delete_buffer(YY_CURRENT_BUFFER); 111 : 112 : /* 113 : * Make a scan buffer with special termination needed by flex. 114 : */ 115 6870 : *scanbuflen = slen; 116 6870 : scanbuf = palloc(slen + 2); 117 6870 : memcpy(scanbuf, str, slen); 118 6870 : scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR; 119 6870 : scanbufhandle = yy_scan_buffer(scanbuf, slen + 2); 120 : 121 6870 : BEGIN(INITIAL); 122 6870 : } 123 : 124 : 125 : /* 126 : * Called after parsing is done to clean up after cube_scanner_init() 127 : */ 128 : void 129 6810 : cube_scanner_finish(void) 130 : { 131 6810 : yy_delete_buffer(scanbufhandle); 132 6810 : pfree(scanbuf); 133 6810 : }