blob: e7381809cc8563affc724fa4d7b758c9d133d52b [file] [log] [blame]
Mark Slee31985722006-05-24 21:45:31 +00001%{
2
3/**
4 * Thrift parser.
5 *
6 * This parser is used on a thrift definition file.
7 *
8 * @author Mark Slee <mcslee@facebook.com>
9 */
10
11#include <stdio.h>
12#include "main.h"
13#include "globals.h"
14#include "parse/t_program.h"
15
Mark Slee9cb7c612006-09-01 22:17:45 +000016int y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +000017
18%}
19
20%union {
21 char* id;
22 int iconst;
Mark Slee52f643d2006-08-09 00:03:43 +000023 bool tbool;
Mark Slee31985722006-05-24 21:45:31 +000024 t_type* ttype;
25 t_typedef* ttypedef;
26 t_enum* tenum;
27 t_struct* tstruct;
28 t_service* tservice;
29 t_function* tfunction;
30 t_field* tfield;
Mark Slee31985722006-05-24 21:45:31 +000031 t_constant* tconstant;
32}
33
34/** Strings and constants */
35%token<id> tok_identifier
36%token<iconst> tok_int_constant
37
Mark Slee9cb7c612006-09-01 22:17:45 +000038/** Namespace */
39%token tok_namespace
40
Mark Slee31985722006-05-24 21:45:31 +000041/** Base datatypes */
Mark Slee78f58e22006-09-02 04:17:07 +000042%token tok_bool
Mark Slee31985722006-05-24 21:45:31 +000043%token tok_byte
44%token tok_string
Mark Slee9cb7c612006-09-01 22:17:45 +000045%token tok_i16
Mark Slee31985722006-05-24 21:45:31 +000046%token tok_i32
Mark Slee31985722006-05-24 21:45:31 +000047%token tok_i64
Mark Slee9cb7c612006-09-01 22:17:45 +000048%token tok_double
Mark Slee31985722006-05-24 21:45:31 +000049
50/** Complex Types */
51%token tok_map
52%token tok_list
53%token tok_set
54
55/** Function types */
56%token tok_void
57
58/** Modifiers */
59%token tok_async
60
61/** Thrift actions */
62%token tok_typedef
63%token tok_struct
Mark Slee9cb7c612006-09-01 22:17:45 +000064%token tok_xception
65%token tok_throws
Mark Slee31985722006-05-24 21:45:31 +000066%token tok_service
67%token tok_enum
68
69/** Types */
70%type<ttype> BaseType
Mark Sleee8540632006-05-30 09:24:40 +000071%type<ttype> ContainerType
72%type<ttype> MapType
73%type<ttype> SetType
74%type<ttype> ListType
Mark Slee31985722006-05-24 21:45:31 +000075
Mark Slee9cb7c612006-09-01 22:17:45 +000076%type<id> Namespace
77
Mark Slee31985722006-05-24 21:45:31 +000078%type<ttypedef> Typedef
79%type<ttype> DefinitionType
80
81%type<tfield> Field
82%type<ttype> FieldType
Mark Sleee8540632006-05-30 09:24:40 +000083%type<tstruct> FieldList
Mark Slee9cb7c612006-09-01 22:17:45 +000084%type<tstruct> ThrowsOptional
Mark Slee31985722006-05-24 21:45:31 +000085
86%type<tenum> Enum
87%type<tenum> EnumDefList
88%type<tconstant> EnumDef
89
90%type<tstruct> Struct
Mark Slee9cb7c612006-09-01 22:17:45 +000091%type<tstruct> Xception
Mark Slee31985722006-05-24 21:45:31 +000092
93%type<tservice> Service
94
95%type<tfunction> Function
Mark Slee31985722006-05-24 21:45:31 +000096%type<ttype> FunctionType
97%type<tservice> FunctionList
98
Mark Slee52f643d2006-08-09 00:03:43 +000099%type<tbool> AsyncOptional
100
Mark Slee31985722006-05-24 21:45:31 +0000101%%
102
103/** Thrift Grammar */
104
105Program:
106 DefinitionList
107 {
108 pdebug("Program -> DefinitionList");
109 }
110
111DefinitionList:
112 DefinitionList Definition
113 {
114 pdebug("DefinitionList -> DefinitionList Definition");
115 }
116|
117 {
118 pdebug("DefinitionList -> ");
119 }
120
121Definition:
Mark Slee9cb7c612006-09-01 22:17:45 +0000122 Namespace
123 {
124 pdebug("Definition -> Namespace");
125 g_program->set_namespace($1);
126 }
127| Typedef
Mark Slee31985722006-05-24 21:45:31 +0000128 {
129 pdebug("Definition -> Typedef");
130 g_program->add_typedef($1);
131 }
132| Enum
133 {
134 pdebug("Definition -> Enum");
135 g_program->add_enum($1);
136 }
137| Struct
138 {
139 pdebug("Definition -> Struct");
140 g_program->add_struct($1);
141 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000142| Xception
143 {
144 pdebug("Definition -> Xception");
145 g_program->add_xception($1);
146 }
Mark Slee31985722006-05-24 21:45:31 +0000147| Service
148 {
149 pdebug("Definition -> Service");
150 g_program->add_service($1);
Mark Slee9cb7c612006-09-01 22:17:45 +0000151 }
152
153Namespace:
154 tok_namespace tok_identifier
155 {
156 pdebug("Namespace -> tok_namespace tok_identifier");
157 $$ = $2;
158 }
Mark Slee31985722006-05-24 21:45:31 +0000159
160Typedef:
161 tok_typedef DefinitionType tok_identifier
162 {
163 pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
Mark Slee31985722006-05-24 21:45:31 +0000164 t_typedef *td = new t_typedef($2, $3);
165 $$ = td;
166 }
167
168Enum:
169 tok_enum tok_identifier '{' EnumDefList '}'
170 {
171 pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
172 $$ = $4;
173 $$->set_name($2);
174 }
175
176EnumDefList:
177 EnumDefList ',' EnumDef
178 {
179 pdebug("EnumDefList -> EnumDefList EnumDef");
180 $$ = $1;
181 $$->append($3);
182 }
183| EnumDef
184 {
185 pdebug("EnumDefList -> EnumDef");
186 $$ = new t_enum;
187 $$->append($1);
188 }
189|
190 {
191 pdebug("EnumDefList -> ");
192 $$ = new t_enum;
193 }
194
195EnumDef:
196 tok_identifier '=' tok_int_constant
197 {
Mark Sleee8540632006-05-30 09:24:40 +0000198 pdebug("EnumDef => tok_identifier = tok_int_constant");
Mark Slee31985722006-05-24 21:45:31 +0000199 if ($3 < 0) {
200 printf("WARNING (%d): Negative value supplied for enum %s.\n", yylineno, $1);
201 }
Mark Slee31985722006-05-24 21:45:31 +0000202 $$ = new t_constant($1, $3);
203 }
204|
205 tok_identifier
206 {
207 pdebug("EnumDef => tok_identifier");
208 $$ = new t_constant($1);
209 }
210
211Struct:
212 tok_struct tok_identifier '{' FieldList '}'
213 {
214 pdebug("Struct -> tok_struct tok_identifier { FieldList }");
Mark Sleee8540632006-05-30 09:24:40 +0000215 $4->set_name($2);
216 $$ = $4;
Mark Slee9cb7c612006-09-01 22:17:45 +0000217 y_field_val = -1;
218 }
219
220Xception:
221 tok_xception tok_identifier '{' FieldList '}'
222 {
223 pdebug("Xception -> tok_xception tok_identifier { FieldList }");
224 $4->set_name($2);
225 $4->set_xception(true);
226 $$ = $4;
227 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000228 }
229
230Service:
231 tok_service tok_identifier '{' FunctionList '}'
232 {
233 pdebug("Service -> tok_service tok_identifier { FunctionList }");
234 $$ = $4;
235 $$->set_name($2);
236 }
237
238FunctionList:
Mark Slee9cb7c612006-09-01 22:17:45 +0000239 FunctionList Function CommaOptional
Mark Slee31985722006-05-24 21:45:31 +0000240 {
241 pdebug("FunctionList -> FunctionList Function");
242 $$ = $1;
243 $1->add_function($2);
244 }
245|
246 {
247 pdebug("FunctionList -> ");
248 $$ = new t_service;
249 }
250
Mark Slee9cb7c612006-09-01 22:17:45 +0000251CommaOptional:
252 ','
253 {}
254|
255 {}
256
Mark Slee31985722006-05-24 21:45:31 +0000257Function:
Mark Slee9cb7c612006-09-01 22:17:45 +0000258 FunctionType AsyncOptional tok_identifier '(' FieldList ')' ThrowsOptional
Mark Slee31985722006-05-24 21:45:31 +0000259 {
Mark Sleeb15a68b2006-06-07 06:46:24 +0000260 $5->set_name(std::string($3) + "_args");
Mark Slee9cb7c612006-09-01 22:17:45 +0000261 $$ = new t_function($1, $3, $5, $7, $2);
262 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000263 }
264
Mark Slee52f643d2006-08-09 00:03:43 +0000265AsyncOptional:
266 tok_async
Mark Slee31985722006-05-24 21:45:31 +0000267 {
Mark Slee52f643d2006-08-09 00:03:43 +0000268 $$ = true;
269 }
270|
271 {
272 $$ = false;
Mark Slee31985722006-05-24 21:45:31 +0000273 }
274
Mark Slee9cb7c612006-09-01 22:17:45 +0000275ThrowsOptional:
276 tok_throws '(' FieldList ')'
277 {
278 $$ = $3;
279 }
280|
281 {
282 $$ = new t_struct;
283 }
284
Mark Slee31985722006-05-24 21:45:31 +0000285FieldList:
286 FieldList ',' Field
287 {
288 pdebug("FieldList -> FieldList , Field");
289 $$ = $1;
290 $$->append($3);
291 }
292| Field
293 {
294 pdebug("FieldList -> Field");
Mark Sleee8540632006-05-30 09:24:40 +0000295 $$ = new t_struct;
Mark Slee31985722006-05-24 21:45:31 +0000296 $$->append($1);
297 }
298|
299 {
300 pdebug("FieldList -> ");
Mark Sleee8540632006-05-30 09:24:40 +0000301 $$ = new t_struct;
Mark Slee31985722006-05-24 21:45:31 +0000302 }
303
304Field:
305 FieldType tok_identifier '=' tok_int_constant
306 {
Mark Sleee8540632006-05-30 09:24:40 +0000307 pdebug("Field -> FieldType tok_identifier = tok_int_constant");
Mark Slee9cb7c612006-09-01 22:17:45 +0000308 if ($4 <= 0) {
309 printf("WARNING (%d): Nonpositive value (%d) not allowed as a field key for '%s'.\n", yylineno, $4, $2);
310 $4 = y_field_val--;
Mark Slee31985722006-05-24 21:45:31 +0000311 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000312 $$ = new t_field($1, $2, $4);
Mark Slee31985722006-05-24 21:45:31 +0000313 }
314| FieldType tok_identifier
315 {
Mark Sleee8540632006-05-30 09:24:40 +0000316 pdebug("Field -> FieldType tok_identifier");
Mark Slee9cb7c612006-09-01 22:17:45 +0000317 printf("WARNING (%d): No field key specified for '%s', resulting protocol may have conflicts or not be backwards compatible!\n", yylineno, $2);
318 $$ = new t_field($1, $2, y_field_val--);
Mark Slee31985722006-05-24 21:45:31 +0000319 }
320
321DefinitionType:
322 BaseType
323 {
324 pdebug("DefinitionType -> BaseType");
325 $$ = $1;
326 }
Mark Sleee8540632006-05-30 09:24:40 +0000327| ContainerType
328 {
329 pdebug("DefinitionType -> ContainerType");
330 $$ = $1;
331 }
Mark Slee31985722006-05-24 21:45:31 +0000332
333FunctionType:
334 FieldType
335 {
Mark Sleee8540632006-05-30 09:24:40 +0000336 pdebug("FunctionType -> FieldType");
Mark Slee31985722006-05-24 21:45:31 +0000337 $$ = $1;
338 }
339| tok_void
340 {
Mark Sleee8540632006-05-30 09:24:40 +0000341 pdebug("FunctionType -> tok_void");
Mark Slee31985722006-05-24 21:45:31 +0000342 $$ = g_program->get_void_type();
343 }
344
345FieldType:
346 tok_identifier
347 {
Mark Sleee8540632006-05-30 09:24:40 +0000348 pdebug("FieldType -> tok_identifier");
349 $$ = g_program->get_custom_type($1);
350 if ($$ == NULL) {
351 yyerror("Type \"%s\" has not been defined.", $1);
352 exit(1);
353 }
Mark Slee31985722006-05-24 21:45:31 +0000354 }
355| BaseType
356 {
Mark Sleee8540632006-05-30 09:24:40 +0000357 pdebug("FieldType -> BaseType");
358 $$ = $1;
359 }
360| ContainerType
361 {
362 pdebug("FieldType -> ContainerType");
Mark Slee31985722006-05-24 21:45:31 +0000363 $$ = $1;
364 }
365
366BaseType:
367 tok_string
368 {
369 pdebug("BaseType -> tok_string");
370 $$ = g_program->get_string_type();
371 }
Mark Slee78f58e22006-09-02 04:17:07 +0000372| tok_bool
373 {
374 pdebug("BaseType -> tok_bool");
375 $$ = g_program->get_bool_type();
376 }
Mark Slee31985722006-05-24 21:45:31 +0000377| tok_byte
378 {
379 pdebug("BaseType -> tok_byte");
380 $$ = g_program->get_byte_type();
381 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000382| tok_i16
383 {
384 pdebug("BaseType -> tok_i16");
385 $$ = g_program->get_i16_type();
386 }
Mark Slee31985722006-05-24 21:45:31 +0000387| tok_i32
388 {
389 pdebug("BaseType -> tok_i32");
390 $$ = g_program->get_i32_type();
391 }
Mark Slee31985722006-05-24 21:45:31 +0000392| tok_i64
393 {
394 pdebug("BaseType -> tok_i64");
395 $$ = g_program->get_i64_type();
396 }
Mark Slee31985722006-05-24 21:45:31 +0000397
Mark Sleee8540632006-05-30 09:24:40 +0000398ContainerType:
399 MapType
400 {
401 pdebug("ContainerType -> MapType");
402 $$ = $1;
403 }
404| SetType
405 {
406 pdebug("ContainerType -> SetType");
407 $$ = $1;
408 }
409| ListType
410 {
411 pdebug("ContainerType -> ListType");
412 $$ = $1;
413 }
414
415MapType:
416 tok_map '<' FieldType ',' FieldType '>'
417 {
418 pdebug("MapType -> tok_map <FieldType, FieldType>");
419 $$ = new t_map($3, $5);
420 }
421
422SetType:
423 tok_set '<' FieldType '>'
424 {
425 pdebug("SetType -> tok_set<FieldType>");
426 $$ = new t_set($3);
427 }
428
429ListType:
430 tok_list '<' FieldType '>'
431 {
432 pdebug("ListType -> tok_list<FieldType>");
433 $$ = new t_list($3);
434 }
435
Mark Slee31985722006-05-24 21:45:31 +0000436%%