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 : #include "segdata.h" 10 : #include "segparse.h" /* must be after segdata.h for SEG */ 11 : } 12 : 13 : %{ 14 : /* LCOV_EXCL_START */ 15 : 16 : /* No reason to constrain amount of data slurped */ 17 : #define YY_READ_BUF_SIZE 16777216 18 : 19 : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */ 20 : #undef fprintf 21 : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg) 22 : 23 : static void 24 : fprintf_to_ereport(const char *fmt, const char *msg) 25 : { 26 : ereport(ERROR, (errmsg_internal("%s", msg))); 27 : } 28 : %} 29 : 30 : %option reentrant 31 : %option bison-bridge 32 : %option 8bit 33 : %option never-interactive 34 : %option nodefault 35 : %option noinput 36 : %option nounput 37 : %option noyywrap 38 : %option noyyalloc 39 : %option noyyrealloc 40 : %option noyyfree 41 : %option warn 42 : %option prefix="seg_yy" 43 : 44 : 45 : range (\.\.)(\.)? 46 : plumin (\'\+\-\')|(\(\+\-)\) 47 : integer [+-]?[0-9]+ 48 : real [+-]?[0-9]+\.[0-9]+ 49 : float ({integer}|{real})([eE]{integer})? 50 : 51 : %% 52 : 53 : {range} yylval->text = yytext; return RANGE; 54 : {plumin} yylval->text = yytext; return PLUMIN; 55 : {float} yylval->text = yytext; return SEGFLOAT; 56 : \< yylval->text = "<"; return EXTENSION; 57 : \> yylval->text = ">"; return EXTENSION; 58 : \~ yylval->text = "~"; return EXTENSION; 59 : [ \t\n\r\f\v]+ /* discard spaces */ 60 : . return yytext[0]; /* alert parser of the garbage */ 61 : 62 : %% 63 : 64 : /* LCOV_EXCL_STOP */ 65 : 66 : void 67 44 : seg_yyerror(SEG *result, struct Node *escontext, yyscan_t yyscanner, const char *message) 68 : { 69 44 : struct yyguts_t *yyg = (struct yyguts_t *) yyscanner; /* needed for yytext 70 : * macro */ 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 5650 : seg_scanner_init(const char *str, yyscan_t *yyscannerp) 100 : { 101 : yyscan_t yyscanner; 102 : 103 5650 : if (yylex_init(yyscannerp) != 0) 104 0 : elog(ERROR, "yylex_init() failed: %m"); 105 : 106 5650 : yyscanner = *yyscannerp; 107 : 108 5650 : yy_scan_string(str, yyscanner); 109 5650 : } 110 : 111 : 112 : /* 113 : * Called after parsing is done to clean up after seg_scanner_init() 114 : */ 115 : void 116 5632 : seg_scanner_finish(yyscan_t yyscanner) 117 : { 118 5632 : yylex_destroy(yyscanner); 119 5632 : } 120 : 121 : /* 122 : * Interface functions to make flex use palloc() instead of malloc(). 123 : * It'd be better to make these static, but flex insists otherwise. 124 : */ 125 : 126 : void * 127 22600 : yyalloc(yy_size_t size, yyscan_t yyscanner) 128 : { 129 22600 : return palloc(size); 130 : } 131 : 132 : void * 133 0 : yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner) 134 : { 135 0 : if (ptr) 136 0 : return repalloc(ptr, size); 137 : else 138 0 : return palloc(size); 139 : } 140 : 141 : void 142 28160 : yyfree(void *ptr, yyscan_t yyscanner) 143 : { 144 28160 : if (ptr) 145 22528 : pfree(ptr); 146 28160 : }