aboutsummaryrefslogtreecommitdiff
path: root/src/belex.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/belex.l')
-rw-r--r--src/belex.l178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/belex.l b/src/belex.l
new file mode 100644
index 0000000..f35f114
--- /dev/null
+++ b/src/belex.l
@@ -0,0 +1,178 @@
1%option nounput
2%option noinput
3
4%{
5#include "backend.h"
6
7enum {
8 T_BOGUS = 256,
9 T_IDENT,
10 T_NUMBER,
11 T_STRING,
12 T_BACKEND,
13 T_HOST,
14 T_PORT
15};
16
17static char const *input_string;
18static size_t input_len;
19static size_t input_pos;
20static char const *string_start;
21static size_t current_pos;
22
23#define YY_INPUT(buf,result,max_size) \
24 do { \
25 size_t n = input_len - input_pos; \
26 if (n > max_size) \
27 n = max_size; \
28 memcpy(buf, input_string, n); \
29 input_pos += n; \
30 result = n; \
31 } while (0)
32
33#define YY_USER_ACTION \
34 current_pos += yyleng;
35
36#define YY_DECL static int yylex(void)
37static int yywrap(void);
38
39static char const *
40input_point(void)
41{
42 return input_string + current_pos;
43}
44
45#define YYSTYPE be_string_t
46#define YYSTYPE_INITIALIZER { NULL, 0 }
47
48static YYSTYPE yylval;
49%}
50
51%x COMMENT STR
52
53%%
54 /* C-style comments */
55"/*" BEGIN(COMMENT);
56<COMMENT>[^*]* /* eat anything that's not a '*' */
57<COMMENT>"*"+[^*/]* /* eat up '*'s not followed by '/'s */
58<COMMENT>"*"+"/" BEGIN(INITIAL);
59
60 /* Single-line comments */
61"//".*\n ;
62#.*\n ;
63
64 /* Multi-line strings */
65"{\"" { BEGIN(STR); string_start = input_point(); }
66<STR>[^\"]* /* eat anything that's not a '"' */
67<STR>"\""+[^"}]* /* eat up '"'s not followed by '}'s */
68<STR>"\""+"}" { BEGIN(INITIAL);
69 yylval.start = string_start;
70 yylval.len = input_point() - yylval.start - 2;
71 return T_STRING;
72 }
73 /* Single-line strings */
74\".*\" {
75 yylval.start = input_point() - yyleng + 1;
76 yylval.len = yyleng - 2;
77 return T_STRING;
78 }
79backend return T_BACKEND;
80".host" return T_HOST;
81".port" return T_PORT;
82"{"|"}"|"="|";" return yytext[0];
83
84[a-zA-Z_][a-zA-Z0-9_.]+ {
85 yylval.start = input_point() - yyleng;
86 yylval.len = yyleng;
87 return T_IDENT;
88 }
89[0-9]+ return T_NUMBER;
90
91[ \t\n]+ ;
92
93. return T_BOGUS;
94
95%%
96int
97yywrap(void)
98{
99 return 1;
100}
101
102static void
103set_input(char const *str, size_t len)
104{
105 input_string = str;
106 input_len = len;
107 input_pos = 0;
108 current_pos = 0;
109}
110
111static int brace_nesting;
112
113static void
114read_backend(regfun_t regfun, void *d)
115{
116 int c;
117 int in_statement;
118 YYSTYPE label, host = YYSTYPE_INITIALIZER, port = YYSTYPE_INITIALIZER;
119
120 if ((c = yylex()) != T_IDENT && c != T_STRING)
121 return;
122 label = yylval;
123 if ((c = yylex()) != '{')
124 return;
125 brace_nesting++;
126 in_statement = 0;
127 while (brace_nesting == 1) {
128 c = yylex();
129 if (c == 0)
130 break;
131 else if (c == '{')
132 brace_nesting++;
133 else if (c == '}')
134 brace_nesting++;
135 else if (in_statement) {
136 if (c == ';')
137 in_statement = 0;
138 } else {
139 in_statement = 1;
140 if (c == T_HOST || c == T_PORT) {
141 YYSTYPE *stk = c == T_HOST ? &host : &port;
142 in_statement = 1;
143 if ((c = yylex()) == '=') {
144 c = yylex();
145 if (c == T_STRING || c == T_IDENT) {
146 *stk = yylval;
147 }
148 }
149 }
150 }
151 }
152 regfun(&label, &host, &port, d);
153}
154
155void
156backend_parser(const char *str, size_t len, regfun_t regfun, void *d)
157{
158 int c;
159
160 set_input(str, len);
161
162 brace_nesting = 0;
163 while ((c = yylex())) {
164 if (brace_nesting == 0) {
165 if (c == T_BACKEND) {
166 read_backend(regfun, d);
167 }
168 }
169 switch (c) {
170 case '{':
171 brace_nesting++;
172 break;
173 case '}':
174 brace_nesting--;
175 break;
176 }
177 }
178}

Return to:

Send suggestions and report system problems to the System administrator.