Line data Source code
1 : %{
2 : /*-------------------------------------------------------------------------
3 : *
4 : * syncrep_scanner.l
5 : * a lexical scanner for synchronous_standby_names
6 : *
7 : * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
8 : * Portions Copyright (c) 1994, Regents of the University of California
9 : *
10 : *
11 : * IDENTIFICATION
12 : * src/backend/replication/syncrep_scanner.l
13 : *
14 : *-------------------------------------------------------------------------
15 : */
16 : #include "postgres.h"
17 :
18 : #include "lib/stringinfo.h"
19 :
20 : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
21 : #undef fprintf
22 : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
23 :
24 : static void
25 0 : fprintf_to_ereport(const char *fmt, const char *msg)
26 : {
27 0 : ereport(ERROR, (errmsg_internal("%s", msg)));
28 : }
29 :
30 : /* Handles to the buffer that the lexer uses internally */
31 : static YY_BUFFER_STATE scanbufhandle;
32 :
33 : static StringInfoData xdbuf;
34 :
35 : %}
36 :
37 : %option 8bit
38 : %option never-interactive
39 : %option nodefault
40 : %option noinput
41 : %option nounput
42 : %option noyywrap
43 : %option warn
44 : %option prefix="syncrep_yy"
45 :
46 : /*
47 : * <xd> delimited identifiers (double-quoted identifiers)
48 : */
49 : %x xd
50 :
51 : space [ \t\n\r\f\v]
52 :
53 : digit [0-9]
54 : ident_start [A-Za-z\200-\377_]
55 : ident_cont [A-Za-z\200-\377_0-9\$]
56 : identifier {ident_start}{ident_cont}*
57 :
58 : dquote \"
59 : xdstart {dquote}
60 : xdstop {dquote}
61 : xddouble {dquote}{dquote}
62 : xdinside [^"]+
63 :
64 : %%
65 : {space}+ { /* ignore */ }
66 0 :
67 : /* brute-force case insensitivity is safer than relying on flex -i */
68 :
69 0 : [Aa][Nn][Yy] { return ANY; }
70 0 : [Ff][Ii][Rr][Ss][Tt] { return FIRST; }
71 :
72 : {xdstart} {
73 0 : initStringInfo(&xdbuf);
74 0 : BEGIN(xd);
75 : }
76 0 : <xd>{xddouble} {
77 0 : appendStringInfoChar(&xdbuf, '"');
78 : }
79 0 : <xd>{xdinside} {
80 0 : appendStringInfoString(&xdbuf, yytext);
81 : }
82 0 : <xd>{xdstop} {
83 0 : yylval.str = xdbuf.data;
84 0 : xdbuf.data = NULL;
85 0 : BEGIN(INITIAL);
86 0 : return NAME;
87 : }
88 : <xd><<EOF>> {
89 0 : yyerror("unterminated quoted identifier");
90 0 : return JUNK;
91 : }
92 :
93 : {identifier} {
94 0 : yylval.str = pstrdup(yytext);
95 0 : return NAME;
96 : }
97 :
98 : {digit}+ {
99 0 : yylval.str = pstrdup(yytext);
100 0 : return NUM;
101 : }
102 :
103 : "*" {
104 0 : yylval.str = "*";
105 0 : return NAME;
106 : }
107 :
108 0 : "," { return ','; }
109 0 : "(" { return '('; }
110 0 : ")" { return ')'; }
111 :
112 0 : . { return JUNK; }
113 0 : %%
114 0 :
115 :
116 : /* Needs to be here for access to yytext */
117 : void
118 0 : syncrep_yyerror(const char *message)
119 : {
120 : /* report only the first error in a parse operation */
121 0 : if (syncrep_parse_error_msg)
122 0 : return;
123 0 : if (yytext[0])
124 0 : syncrep_parse_error_msg = psprintf("%s at or near \"%s\"",
125 : message, yytext);
126 : else
127 0 : syncrep_parse_error_msg = psprintf("%s at end of input",
128 : message);
129 : }
130 :
131 : void
132 0 : syncrep_scanner_init(const char *str)
133 : {
134 0 : Size slen = strlen(str);
135 : char *scanbuf;
136 :
137 : /*
138 : * Might be left over after ereport()
139 : */
140 0 : if (YY_CURRENT_BUFFER)
141 0 : yy_delete_buffer(YY_CURRENT_BUFFER);
142 :
143 : /*
144 : * Make a scan buffer with special termination needed by flex.
145 : */
146 0 : scanbuf = (char *) palloc(slen + 2);
147 0 : memcpy(scanbuf, str, slen);
148 0 : scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
149 0 : scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
150 :
151 : /* Make sure we start in proper state */
152 0 : BEGIN(INITIAL);
153 0 : }
154 :
155 : void
156 0 : syncrep_scanner_finish(void)
157 : {
158 0 : yy_delete_buffer(scanbufhandle);
159 0 : scanbufhandle = NULL;
160 0 : }
|