}
%{
-static JsonPathString scanstring;
-
-/* Handles to the buffer that the lexer uses internally */
-static YY_BUFFER_STATE scanbufhandle;
-static char *scanbuf;
-static int scanbuflen;
+struct jsonpath_yy_extra_type
+{
+ JsonPathString scanstring;
+};
+#define YY_EXTRA_TYPE struct jsonpath_yy_extra_type *
-static void addstring(bool init, char *s, int l);
-static void addchar(bool init, char c);
-static enum yytokentype checkKeyword(void);
-static bool parseUnicode(char *s, int l, struct Node *escontext);
-static bool parseHexChar(char *s, struct Node *escontext);
+static void addstring(bool init, char *s, int l, yyscan_t yyscanner);
+static void addchar(bool init, char c, yyscan_t yyscanner);
+static enum yytokentype checkKeyword(yyscan_t yyscanner);
+static bool parseUnicode(char *s, int l, struct Node *escontext, yyscan_t yyscanner);
+static bool parseHexChar(char *s, struct Node *escontext, yyscan_t yyscanner);
/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
#undef fprintf
%option noyywrap
%option warn
%option prefix="jsonpath_yy"
+%option reentrant
%option bison-bridge
%option noyyalloc
%option noyyrealloc
%%
<xnq>{other}+ {
- addstring(false, yytext, yyleng);
+ addstring(false, yytext, yyleng, yyscanner);
}
<xnq>{blank}+ {
- yylval->str = scanstring;
+ yylval->str = yyextra->scanstring;
BEGIN INITIAL;
- return checkKeyword();
+ return checkKeyword(yyscanner);
}
<xnq>\/\* {
- yylval->str = scanstring;
+ yylval->str = yyextra->scanstring;
BEGIN xc;
}
<xnq>({special}|\") {
- yylval->str = scanstring;
+ yylval->str = yyextra->scanstring;
yyless(0);
BEGIN INITIAL;
- return checkKeyword();
+ return checkKeyword(yyscanner);
}
<xnq><<EOF>> {
- yylval->str = scanstring;
+ yylval->str = yyextra->scanstring;
BEGIN INITIAL;
- return checkKeyword();
+ return checkKeyword(yyscanner);
}
-<xnq,xq,xvq>\\b { addchar(false, '\b'); }
+<xnq,xq,xvq>\\b { addchar(false, '\b', yyscanner); }
-<xnq,xq,xvq>\\f { addchar(false, '\f'); }
+<xnq,xq,xvq>\\f { addchar(false, '\f', yyscanner); }
-<xnq,xq,xvq>\\n { addchar(false, '\n'); }
+<xnq,xq,xvq>\\n { addchar(false, '\n', yyscanner); }
-<xnq,xq,xvq>\\r { addchar(false, '\r'); }
+<xnq,xq,xvq>\\r { addchar(false, '\r', yyscanner); }
-<xnq,xq,xvq>\\t { addchar(false, '\t'); }
+<xnq,xq,xvq>\\t { addchar(false, '\t', yyscanner); }
-<xnq,xq,xvq>\\v { addchar(false, '\v'); }
+<xnq,xq,xvq>\\v { addchar(false, '\v', yyscanner); }
<xnq,xq,xvq>{unicode}+ {
- if (!parseUnicode(yytext, yyleng, escontext))
+ if (!parseUnicode(yytext, yyleng, escontext, yyscanner))
yyterminate();
}
<xnq,xq,xvq>{hex_char} {
- if (!parseHexChar(yytext, escontext))
+ if (!parseHexChar(yytext, escontext, yyscanner))
yyterminate();
}
<xnq,xq,xvq>{unicode}*{unicodefail} {
- jsonpath_yyerror(NULL, escontext,
+ jsonpath_yyerror(NULL, escontext, yyscanner,
"invalid Unicode escape sequence");
yyterminate();
}
<xnq,xq,xvq>{hex_fail} {
- jsonpath_yyerror(NULL, escontext,
+ jsonpath_yyerror(NULL, escontext, yyscanner,
"invalid hexadecimal character sequence");
yyterminate();
}
<xnq,xq,xvq>{unicode}+\\ {
/* throw back the \\, and treat as unicode */
yyless(yyleng - 1);
- if (!parseUnicode(yytext, yyleng, escontext))
+ if (!parseUnicode(yytext, yyleng, escontext, yyscanner))
yyterminate();
}
-<xnq,xq,xvq>\\. { addchar(false, yytext[1]); }
+<xnq,xq,xvq>\\. { addchar(false, yytext[1], yyscanner); }
<xnq,xq,xvq>\\ {
- jsonpath_yyerror(NULL, escontext,
+ jsonpath_yyerror(NULL, escontext, yyscanner,
"unexpected end after backslash");
yyterminate();
}
<xq,xvq><<EOF>> {
- jsonpath_yyerror(NULL, escontext,
+ jsonpath_yyerror(NULL, escontext, yyscanner,
"unterminated quoted string");
yyterminate();
}
<xq>\" {
- yylval->str = scanstring;
+ yylval->str = yyextra->scanstring;
BEGIN INITIAL;
return STRING_P;
}
<xvq>\" {
- yylval->str = scanstring;
+ yylval->str = yyextra->scanstring;
BEGIN INITIAL;
return VARIABLE_P;
}
-<xq,xvq>[^\\\"]+ { addstring(false, yytext, yyleng); }
+<xq,xvq>[^\\\"]+ { addstring(false, yytext, yyleng, yyscanner); }
<xc>\*\/ { BEGIN INITIAL; }
<xc>\* { }
<xc><<EOF>> {
- jsonpath_yyerror(NULL, escontext,
+ jsonpath_yyerror(NULL, escontext, yyscanner,
"unexpected end of comment");
yyterminate();
}
\> { return GREATER_P; }
\${other}+ {
- addstring(true, yytext + 1, yyleng - 1);
- addchar(false, '\0');
- yylval->str = scanstring;
+ addstring(true, yytext + 1, yyleng - 1, yyscanner);
+ addchar(false, '\0', yyscanner);
+ yylval->str = yyextra->scanstring;
return VARIABLE_P;
}
\$\" {
- addchar(true, '\0');
+ addchar(true, '\0', yyscanner);
BEGIN xvq;
}
{blank}+ { /* ignore */ }
\/\* {
- addchar(true, '\0');
+ addchar(true, '\0', yyscanner);
BEGIN xc;
}
{real} {
- addstring(true, yytext, yyleng);
- addchar(false, '\0');
- yylval->str = scanstring;
+ addstring(true, yytext, yyleng, yyscanner);
+ addchar(false, '\0', yyscanner);
+ yylval->str = yyextra->scanstring;
return NUMERIC_P;
}
{decimal} {
- addstring(true, yytext, yyleng);
- addchar(false, '\0');
- yylval->str = scanstring;
+ addstring(true, yytext, yyleng, yyscanner);
+ addchar(false, '\0', yyscanner);
+ yylval->str = yyextra->scanstring;
return NUMERIC_P;
}
{decinteger} {
- addstring(true, yytext, yyleng);
- addchar(false, '\0');
- yylval->str = scanstring;
+ addstring(true, yytext, yyleng, yyscanner);
+ addchar(false, '\0', yyscanner);
+ yylval->str = yyextra->scanstring;
return INT_P;
}
{hexinteger} {
- addstring(true, yytext, yyleng);
- addchar(false, '\0');
- yylval->str = scanstring;
+ addstring(true, yytext, yyleng, yyscanner);
+ addchar(false, '\0', yyscanner);
+ yylval->str = yyextra->scanstring;
return INT_P;
}
{octinteger} {
- addstring(true, yytext, yyleng);
- addchar(false, '\0');
- yylval->str = scanstring;
+ addstring(true, yytext, yyleng, yyscanner);
+ addchar(false, '\0', yyscanner);
+ yylval->str = yyextra->scanstring;
return INT_P;
}
{bininteger} {
- addstring(true, yytext, yyleng);
- addchar(false, '\0');
- yylval->str = scanstring;
+ addstring(true, yytext, yyleng, yyscanner);
+ addchar(false, '\0', yyscanner);
+ yylval->str = yyextra->scanstring;
return INT_P;
}
{realfail} {
- jsonpath_yyerror(NULL, escontext,
+ jsonpath_yyerror(NULL, escontext, yyscanner,
"invalid numeric literal");
yyterminate();
}
{decinteger_junk} {
- jsonpath_yyerror(NULL, escontext,
+ jsonpath_yyerror(NULL, escontext, yyscanner,
"trailing junk after numeric literal");
yyterminate();
}
{decimal_junk} {
- jsonpath_yyerror(NULL, escontext,
+ jsonpath_yyerror(NULL, escontext, yyscanner,
"trailing junk after numeric literal");
yyterminate();
}
{real_junk} {
- jsonpath_yyerror(NULL, escontext,
+ jsonpath_yyerror(NULL, escontext, yyscanner,
"trailing junk after numeric literal");
yyterminate();
}
\" {
- addchar(true, '\0');
+ addchar(true, '\0', yyscanner);
BEGIN xq;
}
\\ {
yyless(0);
- addchar(true, '\0');
+ addchar(true, '\0', yyscanner);
BEGIN xnq;
}
{other}+ {
- addstring(true, yytext, yyleng);
+ addstring(true, yytext, yyleng, yyscanner);
BEGIN xnq;
}
/* LCOV_EXCL_STOP */
+/* see scan.l */
+#undef yyextra
+#define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r)
+
void
jsonpath_yyerror(JsonPathParseResult **result, struct Node *escontext,
+ yyscan_t yyscanner,
const char *message)
{
+ struct yyguts_t * yyg = (struct yyguts_t *) yyscanner; /* needed for yytext macro */
+
/* don't overwrite escontext if it's already been set */
if (SOFT_ERROR_OCCURRED(escontext))
return;
{ 12,false, TIMESTAMP_TZ_P, "timestamp_tz"},
};
-/* Check if current scanstring value is a keyword */
+/*
+ * Check if current scanstring value is a keyword
+ */
static enum yytokentype
-checkKeyword()
+checkKeyword(yyscan_t yyscanner)
{
int res = IDENT_P;
int diff;
*StopHigh = keywords + lengthof(keywords),
*StopMiddle;
- if (scanstring.len > keywords[lengthof(keywords) - 1].len)
+ if (yyextra->scanstring.len > keywords[lengthof(keywords) - 1].len)
return res;
while (StopLow < StopHigh)
{
StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
- if (StopMiddle->len == scanstring.len)
- diff = pg_strncasecmp(StopMiddle->keyword, scanstring.val,
- scanstring.len);
+ if (StopMiddle->len == yyextra->scanstring.len)
+ diff = pg_strncasecmp(StopMiddle->keyword, yyextra->scanstring.val,
+ yyextra->scanstring.len);
else
- diff = StopMiddle->len - scanstring.len;
+ diff = StopMiddle->len - yyextra->scanstring.len;
if (diff < 0)
StopLow = StopMiddle + 1;
else
{
if (StopMiddle->lowercase)
- diff = strncmp(StopMiddle->keyword, scanstring.val,
- scanstring.len);
+ diff = strncmp(StopMiddle->keyword, yyextra->scanstring.val,
+ yyextra->scanstring.len);
if (diff == 0)
res = StopMiddle->val;
return res;
}
-/*
- * Called before any actual parsing is done
- */
-static void
-jsonpath_scanner_init(const char *str, int slen)
-{
- if (slen <= 0)
- slen = strlen(str);
-
- /*
- * Might be left over after ereport()
- */
- yy_init_globals();
-
- /*
- * Make a scan buffer with special termination needed by flex.
- */
-
- scanbuflen = slen;
- scanbuf = palloc(slen + 2);
- memcpy(scanbuf, str, slen);
- scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
- scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
-
- BEGIN(INITIAL);
-}
-
-
-/*
- * Called after parsing is done to clean up after jsonpath_scanner_init()
- */
-static void
-jsonpath_scanner_finish(void)
-{
- yy_delete_buffer(scanbufhandle);
- pfree(scanbuf);
-}
-
/*
* Resize scanstring so that it can append string of given length.
* Reinitialize if required.
*/
static void
-resizeString(bool init, int appendLen)
+resizeString(bool init, int appendLen, yyscan_t yyscanner)
{
if (init)
{
- scanstring.total = Max(32, appendLen);
- scanstring.val = (char *) palloc(scanstring.total);
- scanstring.len = 0;
+ yyextra->scanstring.total = Max(32, appendLen);
+ yyextra->scanstring.val = (char *) palloc(yyextra->scanstring.total);
+ yyextra->scanstring.len = 0;
}
else
{
- if (scanstring.len + appendLen >= scanstring.total)
+ if (yyextra->scanstring.len + appendLen >= yyextra->scanstring.total)
{
- while (scanstring.len + appendLen >= scanstring.total)
- scanstring.total *= 2;
- scanstring.val = repalloc(scanstring.val, scanstring.total);
+ while (yyextra->scanstring.len + appendLen >= yyextra->scanstring.total)
+ yyextra->scanstring.total *= 2;
+ yyextra->scanstring.val = repalloc(yyextra->scanstring.val, yyextra->scanstring.total);
}
}
}
/* Add set of bytes at "s" of length "l" to scanstring */
static void
-addstring(bool init, char *s, int l)
+addstring(bool init, char *s, int l, yyscan_t yyscanner)
{
- resizeString(init, l + 1);
- memcpy(scanstring.val + scanstring.len, s, l);
- scanstring.len += l;
+ resizeString(init, l + 1, yyscanner);
+ memcpy(yyextra->scanstring.val + yyextra->scanstring.len, s, l);
+ yyextra->scanstring.len += l;
}
/* Add single byte "c" to scanstring */
static void
-addchar(bool init, char c)
+addchar(bool init, char c, yyscan_t yyscanner)
{
- resizeString(init, 1);
- scanstring.val[scanstring.len] = c;
+ resizeString(init, 1, yyscanner);
+ yyextra->scanstring.val[yyextra->scanstring.len] = c;
if (c != '\0')
- scanstring.len++;
+ yyextra->scanstring.len++;
}
/* Interface to jsonpath parser */
parsejsonpath(const char *str, int len, struct Node *escontext)
{
JsonPathParseResult *parseresult;
+ yyscan_t scanner;
+ struct jsonpath_yy_extra_type yyext;
+
+ if (jsonpath_yylex_init(&scanner) != 0)
+ elog(ERROR, "yylex_init() failed: %m");
+
+ yyset_extra(&yyext, scanner);
+
+ if (len <= 0)
+ len = strlen(str);
- jsonpath_scanner_init(str, len);
+ jsonpath_yy_scan_bytes(str, len, scanner);
- if (jsonpath_yyparse(&parseresult, escontext) != 0)
- jsonpath_yyerror(NULL, escontext, "invalid input"); /* shouldn't happen */
+ if (jsonpath_yyparse(&parseresult, escontext, scanner) != 0)
+ jsonpath_yyerror(NULL, escontext, scanner, "invalid input"); /* shouldn't happen */
- jsonpath_scanner_finish();
+ jsonpath_yylex_destroy(scanner);
return parseresult;
}
/* Turn hex character into integer */
static bool
-hexval(char c, int *result, struct Node *escontext)
+hexval(char c, int *result, struct Node *escontext, yyscan_t yyscanner)
{
if (c >= '0' && c <= '9')
{
*result = c - 'A' + 0xA;
return true;
}
- jsonpath_yyerror(NULL, escontext, "invalid hexadecimal digit");
+ jsonpath_yyerror(NULL, escontext, yyscanner, "invalid hexadecimal digit");
return false;
}
/* Add given unicode character to scanstring */
static bool
-addUnicodeChar(int ch, struct Node *escontext)
+addUnicodeChar(int ch, struct Node *escontext, yyscan_t yyscanner)
{
if (ch == 0)
{
ereturn(escontext, false,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("could not convert Unicode to server encoding")));
- addstring(false, cbuf, strlen(cbuf));
+ addstring(false, cbuf, strlen(cbuf), yyscanner);
}
return true;
}
/* Add unicode character, processing any surrogate pairs */
static bool
-addUnicode(int ch, int *hi_surrogate, struct Node *escontext)
+addUnicode(int ch, int *hi_surrogate, struct Node *escontext, yyscan_t yyscanner)
{
if (is_utf16_surrogate_first(ch))
{
"surrogate.")));
}
- return addUnicodeChar(ch, escontext);
+ return addUnicodeChar(ch, escontext, yyscanner);
}
/*
* src/backend/utils/adt/json.c
*/
static bool
-parseUnicode(char *s, int l, struct Node *escontext)
+parseUnicode(char *s, int l, struct Node *escontext, yyscan_t yyscanner)
{
int i = 2;
int hi_surrogate = -1;
{
while (s[++i] != '}' && i < l)
{
- if (!hexval(s[i], &si, escontext))
+ if (!hexval(s[i], &si, escontext, yyscanner))
return false;
ch = (ch << 4) | si;
}
{
for (j = 0; j < 4 && i < l; j++)
{
- if (!hexval(s[i++], &si, escontext))
+ if (!hexval(s[i++], &si, escontext, yyscanner))
return false;
ch = (ch << 4) | si;
}
}
- if (! addUnicode(ch, &hi_surrogate, escontext))
+ if (! addUnicode(ch, &hi_surrogate, escontext, yyscanner))
return false;
}
/* Parse sequence of hex-encoded characters */
static bool
-parseHexChar(char *s, struct Node *escontext)
+parseHexChar(char *s, struct Node *escontext, yyscan_t yyscanner)
{
int s2, s3, ch;
- if (!hexval(s[2], &s2, escontext))
+ if (!hexval(s[2], &s2, escontext, yyscanner))
return false;
- if (!hexval(s[3], &s3, escontext))
+ if (!hexval(s[3], &s3, escontext, yyscanner))
return false;
ch = (s2 << 4) | s3;
- return addUnicodeChar(ch, escontext);
+ return addUnicodeChar(ch, escontext, yyscanner);
}
/*
*/
void *
-jsonpath_yyalloc(yy_size_t bytes)
+jsonpath_yyalloc(yy_size_t bytes, yyscan_t yyscanner)
{
return palloc(bytes);
}
void *
-jsonpath_yyrealloc(void *ptr, yy_size_t bytes)
+jsonpath_yyrealloc(void *ptr, yy_size_t bytes, yyscan_t yyscanner)
{
if (ptr)
return repalloc(ptr, bytes);
}
void
-jsonpath_yyfree(void *ptr)
+jsonpath_yyfree(void *ptr, yyscan_t yyscanner)
{
if (ptr)
pfree(ptr);