Line data Source code
1 : %top{ 2 : /* 3 : * A scanner for EMP-style numeric ranges 4 : */ 5 : #include "postgres.h" 6 : 7 : #include "nodes/miscnodes.h" 8 : 9 : /* 10 : * NB: include segparse.h only AFTER including segdata.h, because segdata.h 11 : * contains the definition for SEG. 12 : */ 13 : #include "segdata.h" 14 : #include "segparse.h" 15 : } 16 : 17 : %{ 18 : /* LCOV_EXCL_START */ 19 : 20 : /* No reason to constrain amount of data slurped */ 21 : #define YY_READ_BUF_SIZE 16777216 22 : 23 : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */ 24 : #undef fprintf 25 : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg) 26 : 27 : static void 28 : fprintf_to_ereport(const char *fmt, const char *msg) 29 : { 30 : ereport(ERROR, (errmsg_internal("%s", msg))); 31 : } 32 : 33 : /* Handles to the buffer that the lexer uses internally */ 34 : static YY_BUFFER_STATE scanbufhandle; 35 : static char *scanbuf; 36 : %} 37 : 38 : %option 8bit 39 : %option never-interactive 40 : %option nodefault 41 : %option noinput 42 : %option nounput 43 : %option noyywrap 44 : %option warn 45 : %option prefix="seg_yy" 46 : 47 : 48 : range (\.\.)(\.)? 49 : plumin (\'\+\-\')|(\(\+\-)\) 50 : integer [+-]?[0-9]+ 51 : real [+-]?[0-9]+\.[0-9]+ 52 : float ({integer}|{real})([eE]{integer})? 53 : 54 : %% 55 : 56 : {range} seg_yylval.text = yytext; return RANGE; 57 : {plumin} seg_yylval.text = yytext; return PLUMIN; 58 : {float} seg_yylval.text = yytext; return SEGFLOAT; 59 : \< seg_yylval.text = "<"; return EXTENSION; 60 : \> seg_yylval.text = ">"; return EXTENSION; 61 : \~ seg_yylval.text = "~"; return EXTENSION; 62 : [ \t\n\r\f\v]+ /* discard spaces */ 63 : . return yytext[0]; /* alert parser of the garbage */ 64 : 65 : %% 66 : 67 : /* LCOV_EXCL_STOP */ 68 : 69 : void 70 44 : seg_yyerror(SEG *result, struct Node *escontext, const char *message) 71 : { 72 : /* if we already reported an error, don't overwrite it */ 73 44 : if (SOFT_ERROR_OCCURRED(escontext)) 74 16 : return; 75 : 76 28 : if (*yytext == YY_END_OF_BUFFER_CHAR) 77 : { 78 6 : errsave(escontext, 79 : (errcode(ERRCODE_SYNTAX_ERROR), 80 : errmsg("bad seg representation"), 81 : /* translator: %s is typically "syntax error" */ 82 : errdetail("%s at end of input", message))); 83 : } 84 : else 85 : { 86 22 : errsave(escontext, 87 : (errcode(ERRCODE_SYNTAX_ERROR), 88 : errmsg("bad seg representation"), 89 : /* translator: first %s is typically "syntax error" */ 90 : errdetail("%s at or near \"%s\"", message, yytext))); 91 : } 92 : } 93 : 94 : 95 : /* 96 : * Called before any actual parsing is done 97 : */ 98 : void 99 5646 : seg_scanner_init(const char *str) 100 : { 101 5646 : Size slen = strlen(str); 102 : 103 : /* 104 : * Might be left over after ereport() 105 : */ 106 5646 : if (YY_CURRENT_BUFFER) 107 18 : yy_delete_buffer(YY_CURRENT_BUFFER); 108 : 109 : /* 110 : * Make a scan buffer with special termination needed by flex. 111 : */ 112 5646 : scanbuf = palloc(slen + 2); 113 5646 : memcpy(scanbuf, str, slen); 114 5646 : scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR; 115 5646 : scanbufhandle = yy_scan_buffer(scanbuf, slen + 2); 116 : 117 5646 : BEGIN(INITIAL); 118 5646 : } 119 : 120 : 121 : /* 122 : * Called after parsing is done to clean up after seg_scanner_init() 123 : */ 124 : void 125 5628 : seg_scanner_finish(void) 126 : { 127 5628 : yy_delete_buffer(scanbufhandle); 128 5628 : pfree(scanbuf); 129 5628 : }