blob: 3bf8b53990bb5d04d8f4afe29fc21a4ed7efd3bd [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 Sleef5377b32006-10-10 01:42:59 +000016/**
17 * This global variable is used for automatic numbering of field indices etc.
18 * when parsing the members of a struct. Field values are automatically
19 * assigned starting from -1 and working their way down.
20 */
Mark Slee9cb7c612006-09-01 22:17:45 +000021int y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +000022
23%}
24
Mark Sleef5377b32006-10-10 01:42:59 +000025/**
26 * This structure is used by the parser to hold the data types associated with
27 * various parse nodes.
28 */
Mark Slee31985722006-05-24 21:45:31 +000029%union {
30 char* id;
31 int iconst;
Mark Slee52f643d2006-08-09 00:03:43 +000032 bool tbool;
Mark Slee31985722006-05-24 21:45:31 +000033 t_type* ttype;
34 t_typedef* ttypedef;
35 t_enum* tenum;
36 t_struct* tstruct;
37 t_service* tservice;
38 t_function* tfunction;
39 t_field* tfield;
Mark Slee31985722006-05-24 21:45:31 +000040 t_constant* tconstant;
41}
42
Mark Sleef5377b32006-10-10 01:42:59 +000043/**
44 * Strings identifier
45 */
Mark Slee31985722006-05-24 21:45:31 +000046%token<id> tok_identifier
Mark Slee4f8da1d2006-10-12 02:47:27 +000047%token<id> tok_cpptype
Mark Sleef5377b32006-10-10 01:42:59 +000048
49/**
50 * Integer constant value
51 */
Mark Slee31985722006-05-24 21:45:31 +000052%token<iconst> tok_int_constant
53
Mark Sleef5377b32006-10-10 01:42:59 +000054/**
55 * Namespace keyword
56 */
Mark Slee9cb7c612006-09-01 22:17:45 +000057%token tok_namespace
58
Mark Sleef5377b32006-10-10 01:42:59 +000059/**
60 * Base datatype keywords
61 */
62%token tok_void
Mark Slee78f58e22006-09-02 04:17:07 +000063%token tok_bool
Mark Slee31985722006-05-24 21:45:31 +000064%token tok_byte
65%token tok_string
Mark Slee9cb7c612006-09-01 22:17:45 +000066%token tok_i16
Mark Slee31985722006-05-24 21:45:31 +000067%token tok_i32
Mark Slee31985722006-05-24 21:45:31 +000068%token tok_i64
Mark Slee9cb7c612006-09-01 22:17:45 +000069%token tok_double
Mark Slee31985722006-05-24 21:45:31 +000070
Mark Sleef5377b32006-10-10 01:42:59 +000071/**
72 * Complex type keywords
73 */
Mark Slee31985722006-05-24 21:45:31 +000074%token tok_map
75%token tok_list
76%token tok_set
77
Mark Sleef5377b32006-10-10 01:42:59 +000078/**
79 * Function modifiers
80 */
Mark Slee31985722006-05-24 21:45:31 +000081%token tok_async
82
Mark Sleef5377b32006-10-10 01:42:59 +000083/**
84 * Thrift language keywords
85 */
Mark Slee31985722006-05-24 21:45:31 +000086%token tok_typedef
87%token tok_struct
Mark Slee9cb7c612006-09-01 22:17:45 +000088%token tok_xception
89%token tok_throws
Mark Slee31985722006-05-24 21:45:31 +000090%token tok_service
91%token tok_enum
92
Mark Sleef5377b32006-10-10 01:42:59 +000093/**
94 * Grammar nodes
95 */
96
97%type<id> Namespace
98
Mark Slee31985722006-05-24 21:45:31 +000099%type<ttype> BaseType
Mark Sleee8540632006-05-30 09:24:40 +0000100%type<ttype> ContainerType
101%type<ttype> MapType
102%type<ttype> SetType
103%type<ttype> ListType
Mark Slee31985722006-05-24 21:45:31 +0000104
105%type<ttypedef> Typedef
106%type<ttype> DefinitionType
107
108%type<tfield> Field
109%type<ttype> FieldType
Mark Sleee8540632006-05-30 09:24:40 +0000110%type<tstruct> FieldList
Mark Slee31985722006-05-24 21:45:31 +0000111
112%type<tenum> Enum
113%type<tenum> EnumDefList
114%type<tconstant> EnumDef
115
116%type<tstruct> Struct
Mark Slee9cb7c612006-09-01 22:17:45 +0000117%type<tstruct> Xception
Mark Slee31985722006-05-24 21:45:31 +0000118%type<tservice> Service
119
120%type<tfunction> Function
Mark Slee31985722006-05-24 21:45:31 +0000121%type<ttype> FunctionType
122%type<tservice> FunctionList
123
Mark Sleef5377b32006-10-10 01:42:59 +0000124%type<tstruct> ThrowsOptional
Mark Slee52f643d2006-08-09 00:03:43 +0000125%type<tbool> AsyncOptional
Mark Slee4f8da1d2006-10-12 02:47:27 +0000126%type<id> CppTypeOptional
Mark Slee52f643d2006-08-09 00:03:43 +0000127
Mark Slee31985722006-05-24 21:45:31 +0000128%%
129
Mark Sleef5377b32006-10-10 01:42:59 +0000130/**
131 * Thrift Grammar Implementation.
132 *
133 * For the most part this source file works its way top down from what you
134 * might expect to find in a typical .thrift file, i.e. type definitions and
135 * namespaces up top followed by service definitions using those types.
136 */
Mark Slee31985722006-05-24 21:45:31 +0000137
138Program:
139 DefinitionList
140 {
141 pdebug("Program -> DefinitionList");
142 }
143
144DefinitionList:
145 DefinitionList Definition
146 {
147 pdebug("DefinitionList -> DefinitionList Definition");
148 }
149|
150 {
151 pdebug("DefinitionList -> ");
152 }
153
154Definition:
Mark Slee9cb7c612006-09-01 22:17:45 +0000155 Namespace
156 {
157 pdebug("Definition -> Namespace");
158 g_program->set_namespace($1);
159 }
160| Typedef
Mark Slee31985722006-05-24 21:45:31 +0000161 {
162 pdebug("Definition -> Typedef");
163 g_program->add_typedef($1);
164 }
165| Enum
166 {
167 pdebug("Definition -> Enum");
168 g_program->add_enum($1);
169 }
170| Struct
171 {
172 pdebug("Definition -> Struct");
173 g_program->add_struct($1);
174 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000175| Xception
176 {
177 pdebug("Definition -> Xception");
178 g_program->add_xception($1);
179 }
Mark Slee31985722006-05-24 21:45:31 +0000180| Service
181 {
182 pdebug("Definition -> Service");
183 g_program->add_service($1);
Mark Slee9cb7c612006-09-01 22:17:45 +0000184 }
185
186Namespace:
187 tok_namespace tok_identifier
188 {
189 pdebug("Namespace -> tok_namespace tok_identifier");
190 $$ = $2;
191 }
Mark Slee31985722006-05-24 21:45:31 +0000192
193Typedef:
194 tok_typedef DefinitionType tok_identifier
195 {
196 pdebug("TypeDef -> tok_typedef DefinitionType tok_identifier");
Mark Slee31985722006-05-24 21:45:31 +0000197 t_typedef *td = new t_typedef($2, $3);
198 $$ = td;
199 }
200
201Enum:
202 tok_enum tok_identifier '{' EnumDefList '}'
203 {
204 pdebug("Enum -> tok_enum tok_identifier { EnumDefList }");
205 $$ = $4;
206 $$->set_name($2);
207 }
208
209EnumDefList:
210 EnumDefList ',' EnumDef
211 {
212 pdebug("EnumDefList -> EnumDefList EnumDef");
213 $$ = $1;
214 $$->append($3);
215 }
216| EnumDef
217 {
218 pdebug("EnumDefList -> EnumDef");
219 $$ = new t_enum;
220 $$->append($1);
221 }
222|
223 {
224 pdebug("EnumDefList -> ");
225 $$ = new t_enum;
226 }
227
228EnumDef:
229 tok_identifier '=' tok_int_constant
230 {
Mark Sleee8540632006-05-30 09:24:40 +0000231 pdebug("EnumDef => tok_identifier = tok_int_constant");
Mark Slee31985722006-05-24 21:45:31 +0000232 if ($3 < 0) {
233 printf("WARNING (%d): Negative value supplied for enum %s.\n", yylineno, $1);
234 }
Mark Slee31985722006-05-24 21:45:31 +0000235 $$ = new t_constant($1, $3);
236 }
237|
238 tok_identifier
239 {
240 pdebug("EnumDef => tok_identifier");
241 $$ = new t_constant($1);
242 }
243
244Struct:
245 tok_struct tok_identifier '{' FieldList '}'
246 {
247 pdebug("Struct -> tok_struct tok_identifier { FieldList }");
Mark Sleee8540632006-05-30 09:24:40 +0000248 $4->set_name($2);
249 $$ = $4;
Mark Slee9cb7c612006-09-01 22:17:45 +0000250 y_field_val = -1;
251 }
252
253Xception:
254 tok_xception tok_identifier '{' FieldList '}'
255 {
256 pdebug("Xception -> tok_xception tok_identifier { FieldList }");
257 $4->set_name($2);
258 $4->set_xception(true);
259 $$ = $4;
260 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000261 }
262
263Service:
264 tok_service tok_identifier '{' FunctionList '}'
265 {
266 pdebug("Service -> tok_service tok_identifier { FunctionList }");
267 $$ = $4;
268 $$->set_name($2);
269 }
270
271FunctionList:
Mark Slee9cb7c612006-09-01 22:17:45 +0000272 FunctionList Function CommaOptional
Mark Slee31985722006-05-24 21:45:31 +0000273 {
274 pdebug("FunctionList -> FunctionList Function");
275 $$ = $1;
276 $1->add_function($2);
277 }
278|
279 {
280 pdebug("FunctionList -> ");
281 $$ = new t_service;
282 }
283
Mark Slee9cb7c612006-09-01 22:17:45 +0000284CommaOptional:
285 ','
286 {}
287|
288 {}
289
Mark Slee31985722006-05-24 21:45:31 +0000290Function:
Mark Slee4e755ca2006-09-12 00:46:08 +0000291 AsyncOptional FunctionType tok_identifier '(' FieldList ')' ThrowsOptional
Mark Slee31985722006-05-24 21:45:31 +0000292 {
Mark Sleeb15a68b2006-06-07 06:46:24 +0000293 $5->set_name(std::string($3) + "_args");
Mark Slee4e755ca2006-09-12 00:46:08 +0000294 $$ = new t_function($2, $3, $5, $7, $1);
Mark Slee9cb7c612006-09-01 22:17:45 +0000295 y_field_val = -1;
Mark Slee31985722006-05-24 21:45:31 +0000296 }
297
Mark Slee52f643d2006-08-09 00:03:43 +0000298AsyncOptional:
299 tok_async
Mark Slee31985722006-05-24 21:45:31 +0000300 {
Mark Slee52f643d2006-08-09 00:03:43 +0000301 $$ = true;
302 }
303|
304 {
305 $$ = false;
Mark Slee31985722006-05-24 21:45:31 +0000306 }
307
Mark Slee9cb7c612006-09-01 22:17:45 +0000308ThrowsOptional:
309 tok_throws '(' FieldList ')'
310 {
311 $$ = $3;
312 }
313|
314 {
315 $$ = new t_struct;
316 }
317
Mark Slee31985722006-05-24 21:45:31 +0000318FieldList:
319 FieldList ',' Field
320 {
321 pdebug("FieldList -> FieldList , Field");
322 $$ = $1;
323 $$->append($3);
324 }
325| Field
326 {
327 pdebug("FieldList -> Field");
Mark Sleee8540632006-05-30 09:24:40 +0000328 $$ = new t_struct;
Mark Slee31985722006-05-24 21:45:31 +0000329 $$->append($1);
330 }
331|
332 {
333 pdebug("FieldList -> ");
Mark Sleee8540632006-05-30 09:24:40 +0000334 $$ = new t_struct;
Mark Slee31985722006-05-24 21:45:31 +0000335 }
336
337Field:
338 FieldType tok_identifier '=' tok_int_constant
339 {
Mark Sleee8540632006-05-30 09:24:40 +0000340 pdebug("Field -> FieldType tok_identifier = tok_int_constant");
Mark Slee9cb7c612006-09-01 22:17:45 +0000341 if ($4 <= 0) {
342 printf("WARNING (%d): Nonpositive value (%d) not allowed as a field key for '%s'.\n", yylineno, $4, $2);
343 $4 = y_field_val--;
Mark Slee31985722006-05-24 21:45:31 +0000344 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000345 $$ = new t_field($1, $2, $4);
Mark Slee31985722006-05-24 21:45:31 +0000346 }
347| FieldType tok_identifier
348 {
Mark Sleee8540632006-05-30 09:24:40 +0000349 pdebug("Field -> FieldType tok_identifier");
Mark Slee9cb7c612006-09-01 22:17:45 +0000350 printf("WARNING (%d): No field key specified for '%s', resulting protocol may have conflicts or not be backwards compatible!\n", yylineno, $2);
351 $$ = new t_field($1, $2, y_field_val--);
Mark Slee31985722006-05-24 21:45:31 +0000352 }
353
354DefinitionType:
355 BaseType
356 {
357 pdebug("DefinitionType -> BaseType");
358 $$ = $1;
359 }
Mark Sleee8540632006-05-30 09:24:40 +0000360| ContainerType
361 {
362 pdebug("DefinitionType -> ContainerType");
363 $$ = $1;
364 }
Mark Slee31985722006-05-24 21:45:31 +0000365
366FunctionType:
367 FieldType
368 {
Mark Sleee8540632006-05-30 09:24:40 +0000369 pdebug("FunctionType -> FieldType");
Mark Slee31985722006-05-24 21:45:31 +0000370 $$ = $1;
371 }
372| tok_void
373 {
Mark Sleee8540632006-05-30 09:24:40 +0000374 pdebug("FunctionType -> tok_void");
Mark Slee31985722006-05-24 21:45:31 +0000375 $$ = g_program->get_void_type();
376 }
377
378FieldType:
379 tok_identifier
380 {
Mark Sleee8540632006-05-30 09:24:40 +0000381 pdebug("FieldType -> tok_identifier");
382 $$ = g_program->get_custom_type($1);
383 if ($$ == NULL) {
384 yyerror("Type \"%s\" has not been defined.", $1);
385 exit(1);
386 }
Mark Slee31985722006-05-24 21:45:31 +0000387 }
388| BaseType
389 {
Mark Sleee8540632006-05-30 09:24:40 +0000390 pdebug("FieldType -> BaseType");
391 $$ = $1;
392 }
393| ContainerType
394 {
395 pdebug("FieldType -> ContainerType");
Mark Slee31985722006-05-24 21:45:31 +0000396 $$ = $1;
397 }
398
399BaseType:
400 tok_string
401 {
402 pdebug("BaseType -> tok_string");
403 $$ = g_program->get_string_type();
404 }
Mark Slee78f58e22006-09-02 04:17:07 +0000405| tok_bool
406 {
407 pdebug("BaseType -> tok_bool");
408 $$ = g_program->get_bool_type();
409 }
Mark Slee31985722006-05-24 21:45:31 +0000410| tok_byte
411 {
412 pdebug("BaseType -> tok_byte");
413 $$ = g_program->get_byte_type();
414 }
Mark Slee9cb7c612006-09-01 22:17:45 +0000415| tok_i16
416 {
417 pdebug("BaseType -> tok_i16");
418 $$ = g_program->get_i16_type();
419 }
Mark Slee31985722006-05-24 21:45:31 +0000420| tok_i32
421 {
422 pdebug("BaseType -> tok_i32");
423 $$ = g_program->get_i32_type();
424 }
Mark Slee31985722006-05-24 21:45:31 +0000425| tok_i64
426 {
427 pdebug("BaseType -> tok_i64");
428 $$ = g_program->get_i64_type();
429 }
Mark Sleec98d0502006-09-06 02:42:25 +0000430| tok_double
431 {
432 pdebug("BaseType -> tok_double");
433 $$ = g_program->get_double_type();
434 }
Mark Slee31985722006-05-24 21:45:31 +0000435
Mark Sleee8540632006-05-30 09:24:40 +0000436ContainerType:
437 MapType
438 {
439 pdebug("ContainerType -> MapType");
440 $$ = $1;
441 }
442| SetType
443 {
444 pdebug("ContainerType -> SetType");
445 $$ = $1;
446 }
447| ListType
448 {
449 pdebug("ContainerType -> ListType");
450 $$ = $1;
451 }
452
453MapType:
Mark Slee4f8da1d2006-10-12 02:47:27 +0000454 tok_map CppTypeOptional '<' FieldType ',' FieldType '>'
Mark Sleee8540632006-05-30 09:24:40 +0000455 {
456 pdebug("MapType -> tok_map <FieldType, FieldType>");
Mark Slee4f8da1d2006-10-12 02:47:27 +0000457 $$ = new t_map($4, $6);
458 if ($2 != NULL) {
459 ((t_container*)$$)->set_cpp_name(std::string($2));
460 }
Mark Sleee8540632006-05-30 09:24:40 +0000461 }
462
463SetType:
Mark Slee4f8da1d2006-10-12 02:47:27 +0000464 tok_set CppTypeOptional '<' FieldType '>'
Mark Sleee8540632006-05-30 09:24:40 +0000465 {
466 pdebug("SetType -> tok_set<FieldType>");
Mark Slee4f8da1d2006-10-12 02:47:27 +0000467 $$ = new t_set($4);
468 if ($2 != NULL) {
469 ((t_container*)$$)->set_cpp_name(std::string($2));
470 }
Mark Sleee8540632006-05-30 09:24:40 +0000471 }
472
473ListType:
Mark Slee4f8da1d2006-10-12 02:47:27 +0000474 tok_list CppTypeOptional '<' FieldType '>'
Mark Sleee8540632006-05-30 09:24:40 +0000475 {
476 pdebug("ListType -> tok_list<FieldType>");
Mark Slee4f8da1d2006-10-12 02:47:27 +0000477 $$ = new t_list($4);
478 if ($2 != NULL) {
479 ((t_container*)$$)->set_cpp_name(std::string($2));
480 }
481 }
482
483CppTypeOptional:
484 tok_cpptype
485 {
486 $$ = $1;
487 }
488|
489 {
490 $$ = NULL;
Mark Sleee8540632006-05-30 09:24:40 +0000491 }
492
Mark Slee31985722006-05-24 21:45:31 +0000493%%